epoll使用步骤:
- epoll_create():得到epoll实例
- epoll_ctl() : 设置文件描述符集
- epoll_wait() : 真正在等待的地方
#include <sys/epoll.h>
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 */
};
int epoll_create(int size);
size :不用了,只是提示作用,没有实际限制大小
return :epoll实例的文件描述符epfd
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
epfd :之前创建的
op :
EPOLL_CTL_ADD
注册文件描述符fd,和event内部fd相关联。
EPOLL_CTL_MOD
改变和fd相关的event
EPOLL_CTL_DEL
dereigster文件描述符fd,event将会成为NULL
event :描述和fd相关的参数情况
events :
EPOLLIN :read操作
EPOLLOUT :write操作
EPOLLET :edge-triger边缘触发
int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);
使用代码示例
#define MAX_EVENTS 10
struct epoll_event ev,events[MAX_EVENTS];
//建立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_wait");
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(conne_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);
}
}
}