poll
是 Linux 系统中的一个 I/O 多路复用机制,它允许单个进程/线程处理多个文件描述符上的 I/O 事件。与 select
和 epoll
相比,poll
提供了更简洁的接口,并且避免了 select
的一些限制。
poll
系统调用通过一个 pollfd
结构体数组来监视多个文件描述符。每个 pollfd
结构体包含三个字段:
fd
:要监视的文件描述符。events
:感兴趣的事件(如 POLLIN、POLLOUT)。revents
:实际发生的事件(由内核填充)。poll
的接口比 select
更简洁,不需要重新初始化文件描述符集合。select
不同,poll
没有文件描述符数量的硬性限制。poll
不会像 select
那样在每次调用时都修改文件描述符集合。poll
主要用于需要同时处理多个 I/O 操作的场景,例如:
以下是一个简单的 poll
使用示例,演示如何同时监视标准输入和一个文件描述符:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/poll.h>
int main() {
struct pollfd fds[2];
int ret;
// 监视标准输入
fds[0].fd = STDIN_FILENO;
fds[0].events = POLLIN;
// 假设我们还有一个文件描述符 fd1 需要监视
int fd1 = open("example.txt", O_RDONLY);
if (fd1 == -1) {
perror("open");
return 1;
}
fds[1].fd = fd1;
fds[1].events = POLLIN;
while (1) {
ret = poll(fds, 2, -1); // 阻塞等待事件
if (ret == -1) {
perror("poll");
break;
}
if (fds[0].revents & POLLIN) {
printf("Data is available on stdin\n");
char buf[1024];
read(STDIN_FILENO, buf, sizeof(buf));
printf("Read from stdin: %s\n", buf);
}
if (fds[1].revents & POLLIN) {
printf("Data is available on file descriptor %d\n", fd1);
char buf[1024];
read(fd1, buf, sizeof(buf));
printf("Read from file: %s\n", buf);
}
}
close(fd1);
return 0;
}
close()
函数。poll
默认是阻塞的,如果需要非阻塞行为,可以设置超时参数。poll(fds, nfds, timeout)
中的 timeout
参数来控制阻塞时间。poll
返回的错误码,并采取相应的恢复措施。poll
的返回值,并使用 perror()
或其他错误处理机制来诊断问题。通过理解这些基础概念和常见问题,你可以更有效地使用 poll
来管理多个 I/O 操作。
领取专属 10元无门槛券
手把手带您无忧上云