Linux - poll()

来源:互联网 发布:聪明的一休 知乎 编辑:程序博客网 时间:2024/05/21 22:53

linux man中poll的翻译,poll在设计上解决了select可监听描述符的个数限制,但在一些系统中兼容性并不是很好,因此还是建议使用select来实现简单socket应用,翻译此文仅对epoll()的学习做一个铺垫。

名字
poll - 等待描述符上的事件

摘要

#include <poll.h>int poll(struct pollfd *fds, nfds_t nfds, int timeout);  

描述
poll 的行为与 select 相似:它等待直到描述符集准备好进行I/O操作。

被监控的描述符集由参数 fds 指定,这个参数是一个结构体数组,结构体如下:

struct pollfd {    int   fd;         /* file descriptor */    short events;     /* requested events */    short revents;    /* returned events */};

调用时需要应用 nfds 参数指定 fds 数组中元素的个数。

fd 是一个已经打开的文件的描述符。如果这个参数为负值, 与 events 的通信将被忽略,同时 revents 将返回 0(这为在一次poll()调用中忽略某个文件描述符提供了简洁的办法,即将 fd 置为负数即可,但注意此方法不能忽略描述符0)。

events 是一个输入域,它以位掩码的方式来指定文件描述符fd需要监测的事件,这个变量可以被置为0,这时可以返回的是事件只有POLLHUP/POLLERR/POLLNVAL(见下文)。

revents是一个输出域,由内核赋值当前发生的事件。revents返回events中指定的事件之一,或者POLLHUP/POLLERR/POLLNVAL事件(这三位在events中是没有意义的,当发生条件为ture时则在revents中被置为1)。

如果在任何文件描述符中都没有事件响应,则poll()将被阻塞直到有事件发生。

timeout参数指定poll()等待直到有文件描述符为ready状态的超时时间,在满足以下条件时调用将被返回:

  • 文件描述符变为ready状态
  • 调用被信号处理打断
  • 等待超时

注意超时间隔以系统时钟为原子单位,内核调度延迟意味着阻塞间隔将较少的超出实际间隔。赋值一个负数将会导致一直阻塞。赋值为0则将会立即返回,即使在没有事件ready的状态下。

<poll.h>中定义了eventsrevents中可以设置和返回的位:

  • POLLIN:可进行读取操作
  • POLLPRI:紧急的数据ready(如:TCP的out-of-band数据)
  • POLLOUT:可进行写入操作,然而在socket或这pipe如果写入超过可以利用空间的数据将导致阻塞。
  • POLLRDHUP(Linux 2.6.17及以上版本):socket流的同伴closed连接,或者在写入未完成时shut down。应用时需要保证_GUN_SOURCE宏定义被定义
  • POLLERR:条件错误(只在revents中被返回,在events中被忽略)
  • POLLHUP:挂起(只在revents中被返回,在events中被忽略),注意当在socketpipe等信道中读取时,这个事件仅仅用来指示socket或pipe的伙伴在文件末尾被closed。 在未读取的数据被读取之后,接下来的读取事件将返回0。
  • POLLNVAL:不合法的请求:fd未打开(只在revents中被返回,在events中被忽略)

返回值
成功时返回正数,返回值就是revent中的非零值。超时时返回0。错误时会返回-1,并且在errno中设置了错误码。

错误
EBADF - 指定需要检测的文件描述符集不合法(一个已经关闭的描述符,或者一个出现错误的描述符)
EINTR - 信号被捕捉,详见 signal
EINVAL - nfds 是负数或者 timeout 中的值不合法
ENOMEM - 不能为内部表分配内存

版本
2.1.23及以上

ppoll()

int ppoll(struct pollfd *fds, nfds_t nfds,               const struct timespec *tmo_p, const sigset_t *sigmask);

poll()ppoll()select()pselect() 的作用相同。

0 0
原创粉丝点击