poll函数说明

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
`poll`函数Linux系统编程中用于执行非阻塞的I/O操作的系统调用。它主要用于处理套接字(sockets),文件描述符(file descriptors)等I/O资源。`poll`提供了比`select`和`epoll`更灵活的机制,允许用户指定要监听的文件描述符集,并等待一个或多个文件描述符成为“就绪”状态。 `poll`函数的基本用法如下: ```c #include <poll.h> int poll(struct pollfd *fds, nfds_t nfds, int timeout); ``` 参数说明: - `struct pollfd *fds`:指向`pollfd`结构体数组的指针,每个结构体包含文件描述符和对应的事件掩码。 - `nfds_t nfds`:`pollfd`结构体数组中的元素个数。 - `int timeout`:等待事件的时间,单位是毫秒。如果设置为-1,则`poll`会阻塞直到至少一个文件描述符就绪。如果设置为0,则`poll`会立即返回,不等待任何文件描述符就绪。如果设置为正整数,则`poll`会等待指定的时间。 `pollfd`结构体定义如下: ```c struct pollfd { int fd; // 文件描述符 short events; // 监听的事件类型 short revents; // 文件描述符上发生的事件 }; ``` 事件掩码`events`和返回掩码`revents`可以包含以下值: - `POLLIN`:普通或优先级带的数据可读 - `POLLPRI`:高优先级数据可读 - `POLLOUT`:写操作不会阻塞 - `POLLRDHUP`:套接字对方关闭连接或半关闭连接 - `POLLERR`:发生错误 - `POLLHUP`:挂起 - `POLLNVAL`:文件描述符非法 `poll`函数的返回值是就绪的文件描述符数量,或者在失败的情况下返回-1。 示例代码: ```c struct pollfd fds[1]; int nfds = 1; int ret; // 设置监听的文件描述符 fds[0].fd = STDIN_FILENO; // 标准输入 fds[0].events = POLLIN; // 监听可读事件 // 执行poll操作 ret = poll(fds, nfds, -1); // 阻塞等待 if (ret > 0) { if (fds[0].revents & POLLIN) { // 处理输入事件 } } else { // 处理错误或者无就绪文件描述符的情况 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

武溪嵌人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值