本文目录
epoll_wait
函数是 Linux 中用于事件驱动 I/O 的系统调用之一,它用于等待一个或多个文件描述符上的事件发生,并在事件发生时通知程序。它通常与 epoll_create
、epoll_ctl
一起使用,构成 Linux 下高效的 I/O 多路复用机制。
主要功能
epoll_wait
主要用于等待事件的发生,其功能可以总结如下:
-
等待文件描述符上的事件:
epoll_wait
在调用时会阻塞程序的执行,直到注册的文件描述符上发生了感兴趣的事件。
-
检测事件类型:
- 当文件描述符上发生感兴趣的事件时,
epoll_wait
会返回,并提供有关事件类型的信息。
- 当文件描述符上发生感兴趣的事件时,
-
非阻塞模式:
epoll_wait
可以在非阻塞模式下工作,允许程序轮询事件而不被阻塞。
-
处理多个文件描述符:
epoll_wait
可以等待多个文件描述符上的事件,并在其中任何一个上发生事件时返回。
使用方法
epoll_wait
函数的原型如下:
#include <sys/epoll.h>
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
epfd
:是由epoll_create
创建的 epoll 文件描述符。events
:是一个指向epoll_event
结构体数组的指针,用于存储发生的事件。maxevents
:是events
数组的大小,即最大可以存储的事件数。timeout
:是等待事件发生的超时时间,以毫秒为单位。传递负数表示永远等待,传递 0 表示立即返回,传递正数表示等待指定的毫秒数。
示例代码
以下是使用 epoll_wait
的简单示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/epoll.h>
#define MAX_EVENTS 10
int main() {
int epoll_fd = epoll_create1(0);
if (epoll_fd == -1) {
perror("epoll_create1");
return 1;
}
// 将文件描述符添加到 epoll 实例中
struct epoll_event event;
event.events = EPOLLIN; // 监听可读事件
event.data.fd = STDIN_FILENO; // 标准输入文件描述符
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, STDIN_FILENO, &event) == -1) {
perror("epoll_ctl");
close(epoll_fd);
return 1;
}
// 开始等待事件
struct epoll_event events[MAX_EVENTS];
while (1) {
int num_events = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
if (num_events == -1) {
perror("epoll_wait");
close(epoll_fd);
return 1;
}
for (int i = 0; i < num_events; i++) {
if (events[i].data.fd == STDIN_FILENO) {
// 从标准输入读取数据
char buffer[256];
ssize_t bytes_read = read(STDIN_FILENO, buffer, sizeof(buffer));
if (bytes_read == -1) {
perror("read");
close(epoll_fd);
return 1;
}
printf("Read from stdin: %.*s", (int)bytes_read, buffer);
}
}
}
close(epoll_fd);
return 0;
}
这个示例代码创建了一个 epoll 实例,并将标准输入文件描述符 (STDIN_FILENO
) 添加到 epoll 实例中。然后使用 epoll_wait
函数等待事件的发生。如果标准输入上发生了可读事件,程序将读取数据并打印到控制台上。
总结
epoll_wait
是 Linux 下事件驱动 I/O 的关键部分之一,允许程序高效地等待文件描述符上的事件发生。通过使用 epoll
系列函数,可以实现高性能、高并发的网络编程和 I/O 操作。