在 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助手提供,问题来源于学员提问