poll(2)
名字
poll,ppoll-等待文件描述符上的某些事件
概要
#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <signal.h>
#include <poll.h>
int ppoll(struct pollfd *fds, nfds_t nfds,
const struct timespec *tmo_p, const sigset_t *sigmask);
描述
poll()执行与select(2)类似的任务:它等待一组文件描述符中的一个准备好执行I / O。
在fds参数中指定了要监视的文件描述符集,该参数是以下形式的结构数组:
struct pollfd {
int fd; /* file descriptor 文件描述符*/
short events; /* requested events 请求的事件 */
short revents; /* returned events 返回的事件*/
};
调用者应在nfds中指定fds数组中的项目数。
字段fd包含打开文件的文件描述符。如果此字段为负,则将忽略相应的事件字段,而revents字段将返回零。 (这为忽略单个poll()调用提供了一种简单的方法,只需取消fd字段即可。但是请注意,该技术不能用于忽略文件描述符0。)
字段事件是一个输入参数,位掩码指定应用程序对文件描述符fd感兴趣的事件。该字段可以指定为零,在这种情况下,只能在revents中返回的事件是POLLHUP,POLLERR,和POLLNVAL(请参阅下文)。
字段revents是一个输出参数,由内核填充实际发生的事件。 revents中返回的位可以包括事件中指定的任何位,或值POLLERR,POLLHUP或POLLNVAL之一。 (这三个位在事件字段中是无意义的,只要相应条件为真,就会在revents字段中设置。)
如果对于任何文件描述符都没有发生所请求的事件(也没有错误),则poll()会阻塞直到其中一个事件发生。
timeout参数指定poll()在等待文件描述符准备就绪之前应阻塞的毫秒数。呼叫将一直阻塞,直到发生以下任何一种情况:
* 文件描述符准备就绪;
* 呼叫被信号处理程序中断;
* 超时到期。
请注意,超时间隔将四舍五入为系统时钟的粒度,并且内核调度延迟意味着阻塞间隔可能会少量溢出。 在超时中指定负值表示无限超时。 将超时指定为零会导致poll()立即返回,即使没有准备好文件描述符也是如此。
在事件和revents中返回可被设置的位/定义在**<poll.h>:
POLLIN有要读取的数据。
POLLPRI
有紧急数据要读取(例如,TCP套接字上的带外数据;处于数据包模式的伪终端主设备的从设备状态已更改)
POLLOUT
现在可以进行写操作,尽管写操作会大于套接字或管道中的可用空间(除非设置了O_NONBLOCK*)。
POLLRDHUP(从Linux 2.6.17开始)
流套接字对等方关闭连接,或关闭一半连接。
为了获得此定义,必须定义_GNU_SOURCE功能测试宏(在包含任何头文件之前)。
POLLERR
错误条件(仅在revent中返回;在事件中忽略)。
POLLHUP
挂断(仅在revent中返回;在事件中忽略)。请注意,当从管道(例如管道或流套接字)读取时,
此事件仅指示对等方关闭了其通道的末端。仅当使用完通道中所有未完成的数据后,
从通道中进行的后续读取才会返回0(文件末尾)。
POLLNVAL
无效的请求:fd未打开(仅在revents中返回;在事件中被忽略)。
使用已定义的**_XOPEN_SOURCE进行编译时,还具有以下内容,除了上面列出的位之外,
它们不提供任何其他信息:
POLLRDNORM
相当于POLLIN**。
POLDBDBAND
可以读取优先级带数据(在Linux上通常不使用)。
POLLWRNORM
相当于POLLOUT。
POLLWRBAND
可以写入优先级数据。
Linux也知道但不使用POLLMSG。
ppoll()
. poll()和ppoll()之间的关系类似于select(2)和pselect(2)之间的关系:像pselect(2)一样,ppoll()允许应用程序安全地等待,直到文件描述符准备就绪 或直到捕获到信号为止。
除了超时参数的精度差异外,以下ppoll()调用:
ready = ppoll(&fds,nfds,tmo_p,&sigmask);
等效于原子执行以下调用:
sigset_t origmask;
int timeout;
timeout =(tmo_p == NULL)? -1:
(tmo_p-> tv_sec * 1000 + tmo_p-> tv_nsec / 1000000);
pthread_sigmask(SIG_SETMASK,&sigmask,&origmask);
ready = poll(&fds,nfds,超时);
pthread_sigmask(SIG_SETMASK,&origmask,NULL);
有关为什么需要ppoll()的说明,请参见pselect(2)的说明。
如果将sigmask参数指定为NULL,则不执行信号屏蔽操作(因此ppoll()与poll()的区别仅在于超时参数的精度)。
tmo_p参数指定ppoll()阻止的时间上限。此参数是指向以下形式的结构体指针:
struct timespec {
long tv_sec; / *秒* /
long tv_nsec; / *纳秒* /
};
如果将tmo_p指定为NULL,则ppoll()可以无限期阻塞。
返回值
成功时,将返回正数;这是具有非零revent字段的结构的数量(换句话说,是报告了事件或错误的描述者)。
值为0表示调用超时并且没有文件描述符准备好。如果出错,则返回-1,并正确设置errno。
ERRORS
EFAULT作为参数给出的数组未包含在调用程序的地址空间中。
EINTR在任何请求的事件之前发生了信号;参见signal(7)。
EINVAL nfds值超过RLIMIT_NOFILE值。
ENOMEM没有空间来分配文件描述符表。
版本
在Linux 2.1.23中引入了poll()系统调用。在缺少此系统调用的旧内核上,glibc(和旧的Linux libc)poll()包装函数提供了使用select(2)的仿真。
ppoll()系统调用已添加到内核2.6.16中的Linux中。在glibc 2.4中添加了ppoll()库调用。
符合
poll()符合POSIX.1-2001和POSIX.1-2008。 ppoll()是特定于Linux的。
笔记
一些实现将值为-1的非标准常量INFTIM定义为poll()的超时值。 glibc中未提供此常数。
有关在另一个线程中关闭由poll()监视的文件描述符可能发生的情况的讨论,请参见select(2)。
C库/内核差异
Linux ppoll()系统调用会修改其tmo_p参数。但是,glibc包装器函数通过对传递给系统调用的timeout参数使用局部变量来隐藏此行为。因此,glibc ppoll()函数不会修改其tmo_p参数。
原始ppoll()系统调用具有第五个参数size_t sigsetsize,它指定sigmask参数的字节大小。
glibc ppoll()包装函数将此参数指定为固定值(等于sizeof(sigset_t))。
bugs
请参见select(2)的“ BUGS”部分下的有关杂散就绪通知的讨论。
另请参阅
restart_syscall(2),select(2),select_tut(2),epoll(7),time(7)
版权页
该页面是Linux手册页项目4.04版的一部分。 可以在http://www.kernel.org/doc/man-pages/上找到该项目的描述,有关错误报告的信息以及此页面的最新版本。
Linux 2015-12-28 POLL(2)