1、epoll API
1、 epoll_create函数
- 函数作用
创建一个epoll句柄,参数size用来告诉内核监听的文件描述符的个数,跟内存大小有关。 - 函数原型
#include <sys/epoll.h>
int epoll_create(int size)
size:监听数目
-
返回值:
返回一个文件描述符,这个文件描述符指向一颗平衡二叉树的树根
Linux内核里面是红黑树
2、epoll_ctl 函数 -
函数作用
控制某个epoll监控的文件描述符上的事件:注册、修改、删除。 -
函数原型
int epoll_ctl(int epfd, int op, int fd, struc epoll_event event)
epfd: 为epoll_creat的句柄
op:表示动作,用3个宏来表示:
EPOLL_CTL_ADD (注册新的fd到epfd),
EPOLL_CTL_MOD (修改已经注册的fd的监听事件),
EPOLL_CTL_DEL (从epfd删除一个fd);
event: 告诉内核需要监听的事件
struct epoll_event {
__uint32_t events; / Epoll events /
epoll_data_t data; / User data variable */
};
typedef union epoll_data {
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;
- 函数返回值
3、epoll_wait 函数
- 函数作用
等待所监控文件描述符上有事件的产生 - 函数原型
int epoll_wait(int epfd, struct epoll_event *events, int maxevents,int timeout)
events: 是一个数组,传出参数;用来存内核得到事件的集合,
maxevents: 告之内核这个events有多大,这个maxevents的值不能大于创建epoll_create()时的size,
timeout: 是超时时间
-1: 阻塞
0: 立即返回,非阻塞
0: 指定毫秒
- 返回值:
成功返回有多少文件描述符就绪,出错返回-1
2、epoll 工作流程
int main(0
{
//创建监听的套接子
int lfd = socket();
//绑定
bind();
//监听
listen();
//epoll 树根节点
int epfd = epoll_create(3000);
//存储发送变化的fd对应的信息
struct epoll_event all[3000];
//init
//监听的lfd挂到树上
struct epoll_event ev;
ev.events = EPOLLIN;
ev.data.fd = lfd;
epoll_ctl(epfd,EPOLL_CTL_ADD,LFD,&ev);
while(1)
{
//委托内核去检测事件
int ret = epoll_wait(epfd,all,3000,-1);
//根据ret 遍历all数组
for(int i = 0; i < ret; i ++)
{
//有新的连接
int fd = all[i].data.fd;
if(fd == lfd)
{
//接受链接请求
int cfd = accept();
//cfd 上树
struct epoll_events ev;
ev.events = EPOLLIN;
ev.data.fd = cfd;
epoll_ctl(epfd,epoll_ctl_add,&ev)
}
//已经连接的客户端有数据发过来
else
{
//读数据,
recv();
if(len == 0)
{
close(fd);
epoll_ctl(epfd,epoll_ctl_del,fd,NULL);
}
//写数据
send();
}
}
}
}
3、 epoll代码示例