2.poll
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
poll与select类似,但readfds,writefds,exceptfds都由struct pollfd的数组管理。
要监视的文件描述符集合由fds指定,这是一个结构体数组:
struct pollfd {
int fd; /* file descriptor */
short events; /* requested events */
short revents; /* returned events */
};pollfd成员释义:
fd:打开的文件描述符。如果为负,则对应的events会被忽略,revents返回0。
events:输入参数,fd上感兴趣的事件位掩码。
revents:输出参数,kernel会写入实际发生的事件(events中指定的事件)。初始化为0。
如果要监控的所有fd上没有事件或错误发生,那么poll会一直阻塞直到有事假发生。
nfds:表示fds指向的结构体数组大小。
timeout:指定poll要阻塞等待的毫秒数。如果timeout为负,则会一直阻塞。如果timeout为0,则立即返回。
poll调用阻塞后,直到如下情况返回:
- 一个fd就绪(有事件发生或者出错)
- 被信号处理中断
- timeout时间到达。
常用的事件:
POLLIN:读事件,fd可读。
POLLOUT:写事件,fd可写。
POLLERR:发生错误。
POLLHUP:对端关闭连接时,发生该事件。read返回0,表示fd EOF。
POLLNVAL:fd没有打开。
返回值:
调用成功,返回revents的非零个数。
如果超时时间到达,仍没有事件发生,则返回0。
如果出错,返回-1。
poll与select一样,不能准确知道哪个fd上有事件,只能通过循环遍历,当fd数量较多而实际发生io事件的fd较少时,效率较低。因此poll和select的时间复杂度都是O(n)。
poll与select的区别是,poll没有管理最大fd数量的限制。