poll() - Unix,Linux系统调用
广告
名称poll, ppoll - 等待文件描述符上的某些事件概要
#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
#define _GNU_SOURCE
#include <poll.h>
int ppoll(struct pollfd *fds, nfds_t nfds,
const struct timespec *timeout, const sigset_t *sigmask);
|
描述
poll() 执行与 select(2) 类似的任务:它等待一组文件描述符中的一个准备好执行 I/O。要监视的文件描述符集在 fds 参数中指定,这是一个包含 nfds 个以下形式的结构体的数组
struct pollfd {
int fd; /* file descriptor */
short events; /* requested events */
short revents; /* returned events */
};
|
fd 字段包含打开文件的 文件描述符。events 字段是输入参数,一个位掩码,指定应用程序感兴趣的事件。 revents 字段是输出参数,内核用实际发生的事件填充它。revents 中返回的位可以包含在 events 中指定的任何位,或 POLLERR、POLLHUP 或 POLLNVAL 之一。(这三个位在 events 字段中没有意义,并且每当相应条件为真时,将在 revents 字段中设置它们。) 如果对于任何文件描述符都没有发生任何请求的事件(以及没有错误),则 poll() 将阻塞,直到发生其中一个事件。 timeout 参数以毫秒为单位指定 poll() 将阻塞的超时上限。在 timeout 中指定负值表示无限超时。 可以在 <poll.h> 中定义在 events 和 revents 中可以设置/返回的位。
标签 | 描述 |
POLLIN | 有数据要读取。 |
POLLPRI | | 有紧急数据要读取(例如,TCP 套接字上的带外数据;伪终端主控端在分组模式下已看到从端的状体改变)。 |
POLLOUT | | 现在写入不会阻塞。 |
POLLRDHUP (自 Linux 2.6.17 起) | | 流式套接字对端关闭连接,或关闭连接的写入半部分。必须定义 _GNU_SOURCE 功能测试宏才能获得此定义。 |
POLLERR | | 错误条件(仅输出)。 |
POLLHUP | | 挂起(仅输出)。 |
POLLNVAL | | 无效请求:fd 未打开(仅输出)。 |
使用定义的 _XOPEN_SOURCE 编译时,还可以使用以下内容,它们除了上面列出的位之外没有传达更多信息
标签 | 描述 |
POLLRDNORM | | 等效于 POLLIN。 |
POLLRDBAND | | 可以读取优先级带数据(通常在 Linux 上未使用)。 |
POLLWRNORM | | 等效于 POLLOUT。 |
POLLWRBAND | | 可以写入优先级数据。 |
Linux 也知道 POLLMSG,但不使用它。
ppoll()poll() 和 ppoll() 之间的关系类似于 select() 和 pselect() 之间的关系:与 pselect() 一样,ppoll() 允许应用程序安全地等待,直到文件描述符变为就绪或捕获信号。除了 timeout 参数的差异外,以下 ppoll() 调用
ready = ppoll(&fds, nfds, timeout, &sigmask);
|
等效于 *原子地* 执行以下调用
sigset_t origmask;
sigprocmask(SIG_SETMASK, &sigmask, &origmask);
ready = ppoll(&fds, nfds, timeout);
sigprocmask(SIG_SETMASK, &origmask, NULL);
|
有关 ppoll() 为何必要的原因,请参阅 pselect(2) 的说明。 timeout 参数指定 ppoll() 将阻塞的时间上限。此参数是指向以下形式的结构体的指针
struct timespec {
long tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
|
如果 timeout 指定为 NULL,则 ppoll() 可以无限期阻塞。 返回值成功时,返回正数;这是具有非零 revents 字段的结构体数量(换句话说,那些报告事件或错误的描述符)。值为 0 表示调用超时且没有文件描述符就绪。出错时,返回 -1,并相应设置 errno。错误
标签 | 描述 |
EBADF | 在一组集合中给出了无效的文件描述符。 |
EFAULT | 作为参数给出的数组不包含在调用程序的地址空间中。 |
EINTR | 在任何请求的事件之前发生信号。 |
EINVAL | nfds 值超过 RLIMIT_NOFILE 值。 |
ENOMEM | 没有空间分配文件描述符表。 |
Linux说明Linux ppoll() 系统调用会修改其 timeout 参数。但是,glibc 包装器函数通过使用传递给系统调用的超时参数的局部变量来隐藏此行为。因此,glibc ppoll() 函数不会修改其 timeout 参数。错误请参阅 select(2) 的 BUGS 部分中关于虚假就绪通知的讨论。符合标准
poll() 符合 POSIX.1-2001。ppoll() 是 Linux 特定的。版本poll() 系统调用是在 Linux 2.1.23 中引入的。poll() 库调用是在 libc 5.4.28 中引入的(如果您的内核没有 poll() 系统调用,则提供使用 select() 的仿真)。ppoll() 系统调用是在内核 2.6.16 中添加到 Linux 中的。ppoll() 库调用是在 glibc 2.4 中添加的。 备注某些实现使用值为 -1 的非标准常量 INFTIM 作为 timeout。glibc 中未提供此常量。参见
广告
|