larbin中的poll函数不仅设置了POLLIN而且设置了POLLOUT,这时我们对POLLOUT可能会有这样的疑问,什么时候POLLOUT会发生的,也就是什么时刻可以发送request呢?
问这个问题其实是不了解larbin对socket描述字的设置,其实larbin中的socket都是非阻塞的,而对于非阻塞的socket POLLOUT事件是可以立即返回的。一开始不明白为什么不对打开的socket立即写呢,这是个程序的设计问题,larbin这样设计感觉结构非常清晰,功能模块划分的也比较清楚,这些自己还要学习。
函数名
poll, ppoll - 在一个文件描述符上等待一些事件
大纲
#include
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
#define _GNU_SOURCE
#include
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; /* 文件描述符 */
short events; /* 请求的事件 */
short revents; /* 返回的事件 */
};
fd域包含了一个打开的文件描述符。events域是一个输入参数,是一个应用感兴趣的事件的位图。revents域是一个输出参数,由内核负责填充真正发生的事件。在revents里返回的位可以包括任何在events里设置的位,或者POLLERR,POLLHUP,和POLLNVAL。(这三个位在 events域中没有意义,当相应的条件成立时,revents的位将被设置。)如果没有被请求的事件(而且没有错误)对任何一个文件描述符发生,那么 poll()将阻塞直到其中一个事件发生。可以在events和revents里设置/返回的位定义在:
#define POLLIN 0x0001 /* 数据可读 */
#define POLLPRI 0x0002 /* 紧急数据可读 */
#define POLLOUT 0x0004 /* 写操作不会阻塞 */
#define POLLERR 0x0008 /* 错误条件发生(只对输出) */
#define POLLHUP 0x0010 /* 挂起(只对输出) */
#define POLLNVAL 0x0020 /* 无效请求:fd没有打开(只对输出) */
当编译XPG4.2代码时,还有下面定义:
#ifdef _XOPEN_SOURCE
#define POLLRDNORM 0x0040 /* 正常数据可读 */
#define POLLRDBAND 0x0080 /* 紧急数据可读 */
#define POLLWRNORM 0x0100 /* 写操作不会阻塞 */
#define POLLWRBAND 0x0200 /* 紧急数据可写 */
#endif
最后,Linux知道下面定义:
#ifdef _GNU_SOURCE
#define POLLMSG 0x0400
#endif
参数timeout设置了一个poll()阻塞的上限等待时间,单位为毫秒。设置一个负数意味着没有超时。
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);
请参考pselect(2)的描述来解释ppoll()必要的理由。
参数timeout设置了一个ppoll()阻塞的上限等待时间。这个参数是一个结构的指针,其结构为如下形式:
struct timespec {
long tv_sec; /* 秒 */
long tv_nsec; /* 纳秒 */
};
如果timeout设置为NULL,那么ppoll()可能会无限阻塞。
返回值
成功时,返回正整数;这是revents为非0的结构数(换句话说,那些有事件或错误发生的描述符)。返回值0表示调用超时,而且没有文件描述符准备好。错误发生时,返回-1,并设置适当的错误代码。
错误
EBADF 在其中一个集合中给定了一个无效的文件描述符。
EFAULT 作为参数给定的数组不在调用程序的地址空间。
EINTR 捕获了一个非阻塞的信号。
EINVAL n是负数,或者timeout的值不合法。
ENOMEM select()不能分配内存用于内部表。
LINUX注意
系统调用修改timeout参数。然而,glibc封装函数隐藏了这个行为,这是通过对timeout参数使用一个局部变量来传递给系统调用实现的。因此,glibc pselect()函数不修改timeout参数。
缺陷
参考在缺陷节中对select(2)伪造的准备就绪通知的讨论。
遵照
poll()遵照POSIX.1-2001。ppoll()是Linux特有的。
版本
poll()系统调用在Linux 2.1.23引入。poll()库函数调用在libc 5.4.28引入(如果你的内核不提供poll()系统调用,将通过select()模拟)。
ppoll()在Linux kernel 2.6.16被加入。ppoll()库函数调用在glibc 2.4被加入。
注意
一些实现定义了非标准的常量INFTIM,其值为-1,作为timeout。这个常量在glibc中没有提供。
也可以参考
select(2), select_tut(2), ftm(7)
本文来自ChinaUnix博客,如果查看原文请点: http://blog.chinaunix.net/u/21158/showart_278917.html
问这个问题其实是不了解larbin对socket描述字的设置,其实larbin中的socket都是非阻塞的,而对于非阻塞的socket POLLOUT事件是可以立即返回的。一开始不明白为什么不对打开的socket立即写呢,这是个程序的设计问题,larbin这样设计感觉结构非常清晰,功能模块划分的也比较清楚,这些自己还要学习。
函数名
poll, ppoll - 在一个文件描述符上等待一些事件
大纲
#include
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
#define _GNU_SOURCE
#include
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; /* 文件描述符 */
short events; /* 请求的事件 */
short revents; /* 返回的事件 */
};
fd域包含了一个打开的文件描述符。events域是一个输入参数,是一个应用感兴趣的事件的位图。revents域是一个输出参数,由内核负责填充真正发生的事件。在revents里返回的位可以包括任何在events里设置的位,或者POLLERR,POLLHUP,和POLLNVAL。(这三个位在 events域中没有意义,当相应的条件成立时,revents的位将被设置。)如果没有被请求的事件(而且没有错误)对任何一个文件描述符发生,那么 poll()将阻塞直到其中一个事件发生。可以在events和revents里设置/返回的位定义在:
#define POLLIN 0x0001 /* 数据可读 */
#define POLLPRI 0x0002 /* 紧急数据可读 */
#define POLLOUT 0x0004 /* 写操作不会阻塞 */
#define POLLERR 0x0008 /* 错误条件发生(只对输出) */
#define POLLHUP 0x0010 /* 挂起(只对输出) */
#define POLLNVAL 0x0020 /* 无效请求:fd没有打开(只对输出) */
当编译XPG4.2代码时,还有下面定义:
#ifdef _XOPEN_SOURCE
#define POLLRDNORM 0x0040 /* 正常数据可读 */
#define POLLRDBAND 0x0080 /* 紧急数据可读 */
#define POLLWRNORM 0x0100 /* 写操作不会阻塞 */
#define POLLWRBAND 0x0200 /* 紧急数据可写 */
#endif
最后,Linux知道下面定义:
#ifdef _GNU_SOURCE
#define POLLMSG 0x0400
#endif
参数timeout设置了一个poll()阻塞的上限等待时间,单位为毫秒。设置一个负数意味着没有超时。
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);
请参考pselect(2)的描述来解释ppoll()必要的理由。
参数timeout设置了一个ppoll()阻塞的上限等待时间。这个参数是一个结构的指针,其结构为如下形式:
struct timespec {
long tv_sec; /* 秒 */
long tv_nsec; /* 纳秒 */
};
如果timeout设置为NULL,那么ppoll()可能会无限阻塞。
返回值
成功时,返回正整数;这是revents为非0的结构数(换句话说,那些有事件或错误发生的描述符)。返回值0表示调用超时,而且没有文件描述符准备好。错误发生时,返回-1,并设置适当的错误代码。
错误
EBADF 在其中一个集合中给定了一个无效的文件描述符。
EFAULT 作为参数给定的数组不在调用程序的地址空间。
EINTR 捕获了一个非阻塞的信号。
EINVAL n是负数,或者timeout的值不合法。
ENOMEM select()不能分配内存用于内部表。
LINUX注意
系统调用修改timeout参数。然而,glibc封装函数隐藏了这个行为,这是通过对timeout参数使用一个局部变量来传递给系统调用实现的。因此,glibc pselect()函数不修改timeout参数。
缺陷
参考在缺陷节中对select(2)伪造的准备就绪通知的讨论。
遵照
poll()遵照POSIX.1-2001。ppoll()是Linux特有的。
版本
poll()系统调用在Linux 2.1.23引入。poll()库函数调用在libc 5.4.28引入(如果你的内核不提供poll()系统调用,将通过select()模拟)。
ppoll()在Linux kernel 2.6.16被加入。ppoll()库函数调用在glibc 2.4被加入。
注意
一些实现定义了非标准的常量INFTIM,其值为-1,作为timeout。这个常量在glibc中没有提供。
也可以参考
select(2), select_tut(2), ftm(7)
本文来自ChinaUnix博客,如果查看原文请点: http://blog.chinaunix.net/u/21158/showart_278917.html