epoll事件

博客介绍了epoll中涉及的3个主要函数:epoll_create()、epoll_ctl()和epoll_wait(),还列举了epoll_event的各类事件,如EPOLLIN、EPOLLOUT等。指出epoll在一个文件描述符上只能有一个事件,删除事件只需描述符,且注册事件时要填写epoll_data以区分描述符。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在epoll中,主要涉及到3个函数:epoll_create()、epoll_ctl()以及epoll_wait(),详细内容如下:(《节选自Linux高性能服务器编程》)

其中,epoll_event的事件如下:

– EPOLLIN,读事件

– EPOLLOUT,写事件

– EPOLLPRI,带外数据,与select的异常事件集合对应

– EPOLLRDHUP,TCP连接对端至少写写半关闭

– EPOLLERR,错误事件

– EPOLLET,设置事件为边沿触发

– EPOLLONESHOT,只触发一次,事件自动被删除

      epoll在一个文件描述符上只能有一个事件,在一个描述符上添加多个事件,会产生EEXIST的错误。同样,删除epoll的事件,只需描述符就够了

      epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);

      这里有一个比较重要的问题:从epoll_wait返回的events中,该如何知道是哪个描述符上的事件:在注册epoll事件的时候,一定要填写epoll_data,否则我们将分不清触发的是哪个描述符上的事件。

### epoll支持的事件类型及用法 epoll 是 Linux 中用于实现 I/O 复用的一种机制,能够高效地处理大量文件描述符。它通过 `epoll_ctl` 和 `epoll_wait` 等函数来管理事件和监听文件描述符的状态变化。epoll 支持的事件类型主要包括以下几种[^1]: #### 1. **EPOLLIN** 当文件描述符有数据可读时触发此事件。例如,当一个 socket 或管道中有数据到达时,epoll 将会通知用户程序可以进行读操作。 ```c #define EPOLLIN 0x001 ``` #### 2. **EPOLLOUT** 当文件描述符准备好写入时触发此事件。表示用户程序可以向该文件描述符中写入数据而不会阻塞。 ```c #define EPOLLOUT 0x004 ``` #### 3. **EPOLLRDHUP** 当连接的另一端关闭或终止时触发此事件。通常用于检测 TCP 连接是否被对端关闭。 ```c #define EPOLLRDHUP 0x2000 ``` #### 4. **EPOLLERR** 当文件描述符发生错误时触发此事件。例如,socket 的连接异常断开等情况。 ```c #define EPOLLERR 0x008 ``` #### 5. **EPOLLHUP** 当文件描述符被挂起(hang up)时触发此事件。通常表示连接被意外关闭或设备不可用。 ```c #define EPOLLHUP 0x010 ``` #### 6. **EPOLLET** 表示边缘触发(Edge-Triggered)模式。默认情况下,epoll 使用的是水平触发(Level-Triggered)模式。如果设置此标志,则 epoll 只会在状态从“未就绪”变为“就绪”时通知一次。 ```c #define EPOLLET 0x80000000 ``` #### 示例代码:使用 epoll 监听事件 以下是一个简单的示例代码,展示了如何使用 epoll 来监听文件描述符上的事件。 ```c #include <sys/epoll.h> #include <unistd.h> #include <stdio.h> #define MAX_EVENTS 10 int main() { int epoll_fd = epoll_create1(0); if (epoll_fd == -1) { perror("epoll_create1"); return 1; } struct epoll_event event; event.events = EPOLLIN | EPOLLOUT; // 监听读和写事件 int fd = 0; // 标准输入 event.data.fd = fd; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &event) == -1) { perror("epoll_ctl: add"); return 1; } struct epoll_event events[MAX_EVENTS]; int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1); if (nfds == -1) { perror("epoll_wait"); return 1; } for (int i = 0; i < nfds; i++) { if (events[i].events & EPOLLIN) { printf("EPOLLIN event occurred on fd %d\n", events[i].data.fd); } if (events[i].events & EPOLLOUT) { printf("EPOLLOUT event occurred on fd %d\n", events[i].data.fd); } } close(epoll_fd); return 0; } ``` 上述代码创建了一个 epoll 实例,并添加了一个文件描述符(标准输入)以监听其读和写事件。当事件发生时,程序将输出相应的信息。 #### 其他注意事项 - 如果需要监听信号事件,可以结合 `signalfd` 使用[^2]。通过将信号抽象为文件描述符,可以将其加入 epoll 的监听队列中。 - 在实际应用中,可能还需要根据具体的业务需求设置其他选项或参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值