在 Linux 网络编程中,epoll 是一种高效的 I/O 事件通知机制,用于处理大量并发连接。以下是 epoll 相关核心函数及其功能一览:
1. epoll_create / epoll_create1
- 功能:创建一个 epoll 实例,返回文件描述符(fd)。
- 原型:
int epoll_create(int size); // 传统接口(size 已弃用,但必须 >0) int epoll_create1(int flags); // 更现代的接口(flags: EPOLL_CLOEXEC) - 说明:
size:历史遗留参数,内核动态调整,实际可忽略。flags:如设置EPOLL_CLOEXEC,子进程不继承此 fd。
2. epoll_ctl
功能:向 epoll 实例注册、修改或删除监控的事件。
原型:
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);参数:
epfd:epoll_create 返回的 fd。op:操作类型:EPOLL_CTL_ADD:注册新事件。EPOLL_CTL_MOD:修改已注册事件。EPOLL_CTL_DEL:删除事件(此时 event 可为 NULL)。
fd:要监控的目标文件描述符(如 socket)。event:指向事件配置的结构体。
struct epoll_event:
typedef union epoll_data {
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;
struct epoll_event {
uint32_t events; // 监控的事件类型(位掩码)
epoll_data_t data; // 用户数据(通常保存 fd)
};
3. epoll_wait
- 功能:等待事件触发,返回就绪的事件列表。
- 原型:
int epoll_wait(int epfd, struct epoll_event *events,
int maxevents, int timeout);
- 参数:
events[]:输出参数,存放就绪事件的数组。maxevents:每次能处理的最大事件数(≤数组大小)。timeout:超时时间(毫秒):0:非阻塞立即返回;-1:阻塞直到事件发生;>0:指定超时时间。
常用 events (位掩码)
| 宏定义 | 说明 |
|---|---|
EPOLLIN |
fd 可读(有数据到达)。 |
EPOLLOUT |
fd 可写(通常用于非阻塞写缓冲区就绪)。 |
EPOLLRDHUP |
TCP对端关闭连接或半关闭(需内核 ≥2.6.17)。 |
EPOLLPRI |
urgent/带外数据到达。 |
EPOLLERR |
fd发生错误(默认监控无需显式设置)。 |
EPOLLHUP |
fd挂起(如对端关闭连接后继续写入)。 |
EPOLLET |
Edge Triggered模式(默认Level Triggered)。 |
EPOLLONESHOT` |
fd仅触发一次事件后需重新注册。 |
4. close
- 功能 :关闭epoll实例的文件描述符。
close(epfd);
🌟 关键注意事项
LT vs ET模式
- LT (Level Triggered):默认模式,只要fd处于就绪状态会重复通知。
- ET (Edge Triggered):仅在状态变化时通知一次,需非阻塞读写+循环处理。
- LT (Level Triggered):默认模式,只要fd处于就绪状态会重复通知。
性能优化建议
- ET模式下必须将socket设为非阻塞模式 (
fcntl(fd, F_SETFL, O_NONBLOCK))。
- EPOLLONESHOT适用于避免多线程竞争同一个fd的事件。
- ET模式下必须将socket设为非阻塞模式 (
C++封装示例:GitHub代码链接。
如果需要具体代码示例或深入某个细节,可以告诉我!
内容由零声教学AI助手提供,问题来源于学员提问




