epoll 使用详解--epoll_ctl
添加套接字:
1 | int epoll_ctl( int epfd , int op , int fd , struct epoll_event * event ); |
参数详解:
epfd:就是指定epoll文件描述符。
op : 需要执行的操作,添加,修改,删除,详细如下。
EPOLL_CTL_ADD
在epoll的监视列表中添加一个文件描述符(即参数fd),指定监视的事件类型(参数event)。
EPOLL_CTL_MOD
修改监视列表中已经存在的描述符(即参数fd),修改其监视的事件类型(参数event)。
EPOLL_CTL_DEL
将某监视列表中已经存在的描述符(即参数fd)删除,参数event传NULL。
fd:需要添加,修改,删除的套接字。
event:需要epoll监视的时间类型。
struct epoll_event定义为:
1 2 3 4 5 6 7 8 9 10 11 | typedef union epoll_data { void *ptr; int fd; uint32_t u32; uint64_t u64; } epoll_data_t; struct epoll_event { uint32_t events; /* Epoll 监视的事件类型 */ epoll_data_t data; /* 用户数据 */ }; |
struct epoll_event由两个成员组成,事件类型和用户数据。
data:
我们先说用户数据data,从上面代码可以看到,data是一个联合体类型,可以是指针,文件描述符,整形(机器字长)。这个数据传给epoll以后,epoll不会使用,只会在对应的事件触发后原样的返回给用户。实际开发中一般都是保存添加的套接字的描述符,用于当epoll事件返回时识别事件。如果有需要传其它值也可以,比如改成一个结构体或者对象的地址(可以避免一次使用套接字查找对象操作)。
events:
是一个事件集合,通过位掩码的方式表示不同的事件,可以同时设置多个,通过“|” 连接,可选项如下。
EPOLLIN
文件描述符是否可读。
EPOLLOUT
文件描述符是否可写。
EPOLLRDHUP(Linux 2.6.17以后才能使用)
对端关闭连接(被动),或者套接字处于半关闭状态(主动),这个事件会被触发。当使用边缘触发模式时,很方便写代码测试连接的对端是否关闭了连接。
EPOLLPRI
文件描述符是否异常
EPOLLERR
文件描述符是否错误。如果文件描述符已经关闭,继续写入也会收到这个事件。这个事件用户不设置也会被上报。
EPOLLHUP
套接字被挂起(所谓的被挂起是指??)。这个事件用户不设置也会被上报。
EPOLLET
设置epoll的触发模式为边缘触发模式。如果没有设置这个参数,epoll默认情况下是水平触发模式。详细可以参考后续的【epoll边缘触发与水平触发】。
这是一个输入类型的参数,epoll_wait(2)不会返回这种事件。
EPOLLONESHOT(Linux 2.6.2以后才支持)
设置添加的事件只触发一次,当epoll_wait(2)报告一次事件后,这个文件描述符后续所有的事件都不会再报告。只是禁用,文件描述符还在监视队列中,用户可以通过epoll_ctl()的EPOLL_CTL_MOD重新添加事件。
这是一个输入类型的参数,epoll_wait(2)不会返回这种事件。
EPOLLWAKEUP (Linux 3.5以后才支持)
xxxxx。
这是一个输入类型的参数,epoll_wait(2)不会返回这种事件。
EPOLLEXCLUSIVE (Linux 4.5以后才支持)
xxxxx
这是一个输入类型的参数,epoll_wait(2不会返回这种事件。
返回值:
成功epoll_ctl()返回0。错误返回-1。错误码error会被设置。
错误码:
EBADF :epfd或者fd不是一个有效的文件描述符。
EEXIST :当参数是EPOLL_CTL_ADD时,当添加到fd已经在epfd中时,重复添加。
EINVAL :
1、当epfd不是一个文件描述符,或者fd是一个epfd,或者op是不支持的参数。
2、设置了参数EPOLLEXCLUSIVE,却没有和其它有效的参数一起设置。
3、使用参数EPOLL_CTL_MOD 时同时包含了EPOLLEXCLUSIVE
4、使用参数EPOLL_CTL_MOD 时,当前epfd中的fd之前已经被设置了EPOLLEXCLUSIVE。
5、EPOLLEXCLUSIVE ??????
ELOOP :epoll监视队列是可以添加epoll描述符的,就是支持嵌套。当嵌套关系成环时,或者嵌套深度超过5层时,会报这个错误。
ENOENT :使用EPOLL_CTL_MOD 和EPOLL_CTL_DEL添加 修改时,修改的套接字却不在epoll的监视队列中。
ENOMEM :操作所需要的内存不够。
ENOSPC :当EPOLL_CTL_ADD添加时,已经超过了epoll的规格限制。规格限制在:/proc/sys/fs/epoll/max_user_watches。
EPERM :添加的fd不支持epoll。比如添加的是普通文件描述符。
BUGS:
1、在Linux内核版本2.6.9之前,EPOLL_CTL_DEL操作时,event必须是一个非空的指针,实际并没有使用。2.6.9内核版本以后可以直接设置为NULL。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人