poll
poll
在select
的基础之上进行改进,并避免不需要的检查。但是,当 fd 较多的时候,它的性能还是十分低下的。通过poll
实现的轮询与select
相似,但性能限制有所改善。
#include <poll.h>
int poll (struct pollfd *fds, nfds_t nfds, int timeout);
struct pollfd {
int fd; /* file descriptor */
short events; /* requested events to watch */
short revents; /* returned events witnessed */
};
解释
- 每一个
pollfd
结构体对应一个被观察的 fd ; - 在
pollfd
结构体中,events
字段表示期望被观察的事件(以事件为位掩码表示);revents
字段表示被内核观察到的事件,这个字段由内核来设置。因此,所有在events
字段中被指定的事件都可能出现在revents
中; - 与
select
不同的是,在poll
中,不需要指定对于异常的监测; poll
会返回发生了观察事件的 fd 的数量。当返回0时,说明在达到超时时间后,仍然没有反生任何观察事件;而返回-1说明发生了错误。
一个完整的poll
调用例子
#include <stdio.h>
#include <unistd.h>
#include <poll.h>
#define TIMEOUT 5 /* poll timeout, in seconds */
int main (void) {
struct pollfd fds[2];
int ret;
/* watch stdin for input */
fds[0].fd = STDIN_FILENO;
fds[0].events = POLLIN;
/* watch stdout for ability to write (almost always true) */
fds[1].fd = STDOUT_FILENO;
fds[1].events = POLLOUT;
/* All set, block! */
ret = poll (fds, 2, TIMEOUT * 1000);
if (ret == −1) {
perror ("poll");
return 1;
}
if (!ret) {
printf ("%d seconds elapsed.\n", TIMEOUT);
return 0;
}
if (fds[0].revents & POLLIN)
printf ("stdin is readable\n");
if (fds[1].revents & POLLOUT)
printf ("stdout is writable\n");
return 0;
}
poll
vs select
poll
基于select
进行改进:
poll
不需要用户计算 fd 集合数量的最大值;poll
对应处理 fd 的索引值较大的情况时,效率更高。具体来说,在select
中,如果仅仅检测一个值为900的 fd 时,内核需要从0开始扫描各个 fd ,直到第900个(因为在调用select
时,需要传入值最大的 fd 的数字);而在poll
中,只需要传入一个长度为1的pollfd
数组,从而避免了从1-900的 fd 扫描;- 开发者在调用
poll
时,更加方便。在select
中, fd 集合会在select
调用返回时重新构造,因此在下一次调用select
时,必须重新构造 fd 集合;而在poll
中,由于events
域和revents
域分离,在下一次调用poll
时,开发者不需要再重新构造 fd 集合。
Reference
FEATURED TAGS
algorithm
algorithmproblem
architecturalpattern
architecture
aws
c#
cachesystem
codis
compile
concurrentcontrol
database
dataformat
datastructure
debug
design
designpattern
distributedsystem
django
docker
domain
engineering
freebsd
git
golang
grafana
hackintosh
hadoop
hardware
hexo
http
hugo
ios
iot
java
javaee
javascript
kafka
kubernetes
linux
linuxcommand
linuxio
lock
macos
markdown
microservices
mysql
nas
network
networkprogramming
nginx
node.js
npm
oop
openwrt
operatingsystem
padavan
performance
programming
prometheus
protobuf
python
redis
router
security
shell
software testing
spring
sql
systemdesign
truenas
ubuntu
vmware
vpn
windows
wmware
wordpress
xml
zookeeper