前言
本文章不会从头开始讲解poll,而是在基于了解select的基础上进行讲解以及对比,因此如果你还不了解select,可以看看我的上一篇文章。
接口介绍
参数介绍
先从简单的看起,第三个参数timeout是一个int类型的整型,代表毫秒。当传入大于0的数据时,如500,poll会在500ms内阻塞,超过500ms时返回一次。当传入0时,poll非阻塞等待。传入小于0的数据时,poll阻塞式等待。
第一个参数fds是一个结构体指针,具体定义如下
与select的参数不同,它并不是一个输入输出型参数,而是更接近于一个数组。成员fd表示监视的文件描述符;成员events表示需要系统监听的事件集合;成员revents表示返回的事件集合。事件类型如下表所示:
事件 | 描述 | 是否可作为输入 | 是否可作为输出 |
POLLIN | 数据(包括普通数据和优先数据)可读 | Y | Y |
POLLRDNORM | 普通数据可读 | Y | Y |
POLLRDBAND | 优先级带数据可读(Linux不支持) | Y | Y |
POLLPRI | 高优先级数据可读,比如TCP带外数据 | Y | Y |
POLLOUT | 数据(包括普通数据和优先数据)可写 | Y | Y |
POLLWRNORM | 普通数据可写 | Y | Y |
POLLWRBAND | 优先级带数据可写 | Y | Y |
POLLRDHUP | TCP连接被对方关闭,或者对方关闭了写操作,它由GNU 引入 | Y | Y |
POLLERR | 错误 | N | Y |
POLLHUP | 挂起。比如管道的写端被关闭后,读端描述符上将收到POLLHUP 事件 | N | Y |
POLLNVAL | 文件描述符没有打开 | N | Y |
第二个参数nfds代表fds数组的长度。
返回值
与select相同,当ret大于0时,ret代表有几个fd准备就绪。当ret等于0时,说明select超时返回了。当ret小于0时,说明select调用失败,错误码被设置。
相比于select
poll解决了select能监听fd个数有上限的问题;poll将监听事件与返回事件分离,降低了代码难度,增加了代码的可读性。
select的遍历成本和拷贝成本问题poll仍然没有解决。
使用参考
这里就不贴代码了,poll相比于epoll重要程度不高,使用思路与select类似,并且更方便。有兴趣的可以改改我上一篇文章select的代码。