epoll函数族
(Linux
I/O多路复用技术)
一.函数族成员
-
#include <sys/epoll.h>
-
int epoll_create (int size);
-
int epoll_create1 (int flags);
-
int epoll_ctl (int epfd, int op, int fd, struct epoll_event *event);
-
int epoll_wait (int epfd, struct epoll_event *events, nt maxevents, int timeout);
-
int epoll_pwait (int epfd, struct epoll_event *events, int maxevents, int timeout, const sigset_t *sigmask);
注:其中epoll_create、epoll_ctl、epoll_wait使用较频繁。
二.各成员介绍
1.
epoll_create函数
函数声明:int
epoll_create(int size);
函数说明:该函数生成一个epoll专用的文件描述符,其中的参数是指定生成描述符的最大范围(在linux2.6.8版本后size参数被忽略,但必须大于0)。
返回值:成功-非负的文件描述符
失败-返回-1 并设置errno
2.epoll_ctl函数
函数声明:int
epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
函数说明:该函数用于控制某个文件描述符上的事件,可以注册事件、修改事件、删除事件。
参数:
epfd:由 epoll_create 生成的epoll专用的文件描述符;
op:要进行的操作,可能的取值EPOLL_CTL_ADD注册、EPOLL_CTL_MOD修改、EPOLL_CTL_DEL删除;
fd:关联的文件描述符;
event:指向epoll_event的指针;
返回值:成功则返回0,失败则返回-1。
注:struct
epoll_event结构体的定义:
-
typedef union epoll_data {
-
void *ptr;
-
int fd;
-
uint32_t u32;
-
uint64_t u64;
-
} epoll_data_t;
-
-
struct epoll_event {
-
uint32_t events; /* Epoll events */
-
epoll_data_t data; /* User data variable */
-
};
events字段是表示感兴趣的事件和被触发的事件,可能的取值为(或的关系):
EPOLLIN: 表示对应的文件描述符可以读;
EPOLLOUT: 表示对应的文件描述符可以写;
EPOLLPRI: 表示对应的文件描述符有紧急的数据可读;
EPOLLERR: 表示对应的文件描述符发生错误(epoll_wait会始终监测,不需设置);
EPOLLHUP: 表示对应的文件描述符被挂断(epoll_wait会始终监测,不需设置);
EPOLLET: 表示对应的文件描述符有事件发生 ;
EPOLLONESHOT : 表示对应的文件描述符只监测一次;
EPOLLET: 表示是ET模式(缺省是LT模式),这是高速工作方式,只支持no-block
socket。
3.epoll_wait函数
函数声明:int
epoll_wait(int epfd, struct epoll_event *events,
int maxevents, int
timeout);
函数说明:该函数用于轮询I/O事件的发生。
参数:
epfd:由epoll_create 生成的epoll专用的文件描述符;
epoll_event:用于回传代处理事件的数组;
maxevents:每次能处理的事件数;
timeout:等待I/O事件发生的超时值;
返回值:返回发生事件数。
例:
-
#define MAX_EVENTS 10
-
struct epoll_event ev, events[MAX_EVENTS];
-
int listen_sock, conn_sock, nfds, epollfd;
-
-
/* Set up listening socket, 'listen_sock' (socket(),bind(), listen()) */
-
-
epollfd = epoll_create(10);
-
if (epollfd == -1) {
-
perror("epoll_create");
-
exit(EXIT_FAILURE);
-
}
-
-
ev.events = EPOLLIN;
-
ev.data.fd = listen_sock;
-
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev) == -1) {
-
perror("epoll_ctl: listen_sock");
-
exit(EXIT_FAILURE);
-
}
-
-
for (;;) {
-
nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
-
if (nfds == -1) {
-
perror("epoll_pwait");
-
exit(EXIT_FAILURE);
-
}
-
-
for (n = 0; n < nfds; ++n) {
-
if (events[n].data.fd == listen_sock) {
-
conn_sock = accept(listen_sock,
-
(struct sockaddr *) &local, &addrlen);
-
if (conn_sock == -1) {
-
perror("accept");
-
exit(EXIT_FAILURE);
-
}
-
setnonblocking(conn_sock);
-
ev.events = EPOLLIN | EPOLLET;
-
ev.data.fd = conn_sock;
-
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock,&ev) == -1) {
-
perror("epoll_ctl:conn_sock");
-
exit(EXIT_FAILURE);
-
}
-
} else {
-
do_use_fd(events[n].data.fd);
-
}
-
}
-
}
阅读(1031) | 评论(0) | 转发(0) |