epoll模型下的简易版code
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <fcntl.h>#define MAX_EVENTS 10
#define NUM_DESCRIPTORS 5 // 模拟多个文件描述符// 处理事件的函数
void handle_event(struct epoll_event *event) {// 如果事件对应的文件描述符是标准输入if (event->data.fd == STDIN_FILENO) {printf("stdin is ready\n");} // 如果事件对应的文件描述符是在标准输入之后模拟的多个描述符中的一个else if (event->data.fd >= STDIN_FILENO + 1 && event->data.fd <= STDIN_FILENO + NUM_DESCRIPTORS) {printf("Descriptor %d is ready\n", event->data.fd);}
}int main() {int epfd, nfds; // epfd 是 epoll 文件描述符,nfds 用于存储实际发生事件的数量struct epoll_event event, events[MAX_EVENTS];int descriptors[NUM_DESCRIPTORS]; // 用于存储模拟的多个文件描述符// 创建 epoll 实例epfd = epoll_create1(0); // 参数:flags,通常为 0,表示默认行为if (epfd == -1) {perror("epoll_create1"); // 如果创建失败,打印错误信息exit(EXIT_FAILURE); // 退出程序并返回失败状态}// 模拟多个文件描述符并添加到 epoll 监听for (int i = 0; i < NUM_DESCRIPTORS; i++) {descriptors[i] = STDIN_FILENO + 1 + i; // 生成模拟的文件描述符event.events = EPOLLIN; // 设置事件类型为可读event.data.fd = descriptors[i]; // 设置事件对应的文件描述符if (epoll_ctl(epfd, EPOLL_CTL_ADD, descriptors[i], &event) == -1) { // 将描述符添加到 epoll 监听perror("epoll_ctl"); // 如果添加失败,打印错误信息exit(EXIT_FAILURE); // 退出程序并返回失败状态}}while (1) {// 等待事件发生nfds = epoll_wait(epfd, events, MAX_EVENTS, -1); // 参数:epoll 文件描述符,事件数组,数组大小,超时时间(-1 表示无限等待)if (nfds == -1) {perror("epoll_wait"); // 如果等待事件时出错,打印错误信息break; // 退出循环}for (int i = 0; i < nfds; i++) {handle_event(&events[i]); // 处理发生的事件}}close(epfd); // 关闭 epoll 文件描述符return 0;
}
```
整体思路:
- 主要是创建一个
epoll
实例,然后模拟多个文件描述符并添加到epoll
进行监听。在一个循环中等待事件发生,并对发生的事件进行相应处理。
实现过程:
- 在
handle_event
函数中定义了对不同文件描述符事件的处理逻辑,比如对标准输入和模拟的其他描述符的事件分别进行输出。 - 在
main
函数中,首先创建epoll
文件描述符epfd
。然后创建模拟的多个文件描述符数组descriptors
。通过循环将这些描述符添加到epoll
监听,并设置相应的事件类型为可读。之后进入一个无限循环,通过epoll_wait
等待事件发生,获取到事件数量nfds
后,对每个事件进行处理。
技术点:
epoll
机制:用于高效地处理大量文件描述符的 I/O 事件。- 事件监听和处理:通过设置事件结构体的属性来指定要监听的事件类型,并在事件发生时进行相应的处理操作。
- 错误处理:对创建
epoll
、添加监听等操作中的错误进行了捕获和处理,以保证程序的健壮性。
另外,看到一个文章解释挺详细,分享大家一起看。
https://zhuanlan.zhihu.com/p/427512269