zoukankan      html  css  js  c++  java
  • poll, ppoll

    poll,ppoll


    poll, ppoll - 等待文件描述符的一些事件
    SYNOPSIS
           #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 *timeout_ts, const sigset_t *sigmask);


    DESCRIPTION
           poll() 类似于select,等待一组文件描述符直到I/O处于可用状态
           
           这组文件描述符是fds数组传入的,成员结构如下:
               struct pollfd {
                   int   fd;         /* 文件描述符 */
                   short events;     /* 请求事件 */
                   short revents;    /* 返回事件 */
               };
            调用者必须通过nfds参数指出fds数组成员的个数.
            
            fd是已经打开的文件的文件描述符,如果fd不可用,或者是非法的,在结构中给出的events会被忽略,同时revents返回0(这样做提供了一个在调用poll函数时忽略文件描述符的简单方法.(使文件描述符无效,就可以在poll的时候忽略掉该fds成员的监控,注意:不能把fd设置成0); 
            
            events:是一个输入型参数,每个bit位指定一个和fd相关的事件,events可以是0,当events是0的时候,revents只能返回三种事件POLLHUP, POLLERR, POLLNVAL.


            revents:是一个输出型参数,内核根据实际发生的事件来填写revents,revents可以返回任何一个在events中填写的事件,或者是POLLERR, POLLHUP, POLLNVAL中的一个.
           
            如果所有fds中的数组成员指定的events中请求的事件都没有发生,poll()将一直阻塞,直到有事件发生.
            
            timeout:指定在没有事件发生时,可以阻塞多少毫秒(ms).
            
            注意:由于每个系统的系统时钟的问题,实际阻塞的时间可能会超出timeout指定的时间. 如果设置timeout为负值,意味着poll将一直等待下去,直到事件发生.如果设置为0,poll会立即返回,不管事件是否发生和.
            
            在events和revents中的bit位定义在<poll.h>中
                    
                  POLLIN 
                        有数据可读
                  POLLPRI
                        有紧急的数据要读.(通过send可以设置收取的是否为紧急数据)
                        http://www.masterraghu.com/subjects/np/introduction/unix_network_programming_v1.3/ch24lev1sec2.html
                  POLLOUT
                        可以写入,但如果没有把fd设置成O_NONBLOCK,较大的数据将会继续阻塞.
                  POLLRDHUP (since Linux 2.6.17)
                        socket链接的对端关闭了链接,或者是链接异常.
                  POLLERR
                        poll函数异常
                  POLLHUP
                        poll函数挂起
                  POLLNVAL
                        fd没有打开.(socket或者文件没有被打开,或者不存在)


            在编译时定义了 _XOPEN_SOURCE, 会有下面的事件


                  POLLRDNORM
                        等同于POLLIN
                        
                  POLLWRNORM
                        等同于POLLOUT
                  POLLWRBAND
                        优先数据可以写入


       ppoll()
            poll和ppoll很相似,就像select和pselect.ppoll允许程序安全的等待,直到文件描述符已经准备好了,或者捕捉到一个退出的信号.


            在timeout参数上,ppoll比poll精确.
               ready = ppoll(&fds, nfds, timeout_ts, &sigmask);
            上面的函数函数调用相当于执行下面的代码:


               sigset_t origmask;
               int timeout;


               timeout = (timeout_ts == NULL) ? -1 :
                         (timeout_ts.tv_sec * 1000 + timeout_ts.tv_nsec / 1000000);
               sigprocmask(SIG_SETMASK, &sigmask, &origmask);
               ready = poll(&fds, nfds, timeout);
               sigprocmask(SIG_SETMASK, &origmask, NULL);


            查看pselect,理解ppoll为什么是首选.


            如果sigmask参数是NULL, ppoll不会监控任何事件,和poll唯一的区别就是timeout参数.


            timeout_ts参数给出一个ppoll阻塞的上限时间.timeout_ts是一个指针,timeout_ts的结构如下:
               struct timespec {
                   long    tv_sec;         /* seconds */
                   long    tv_nsec;        /* nanoseconds */
               };




            timeout_ts如果是NULL,ppoll将一直阻塞到事件发生.
    RETURN VALUE
            成功:返回一个正数,返回值为非0的revents的位数.如果返回0,表示ppoll是超时返回.
            错误:返回-1,并且会设置系统的errno.
    ERRORS
           EFAULT The array given as argument was not contained in the calling program's address space.
                    数组参数不可用
           EINTR  A signal occurred before any requested event; see signal(7).
                    捕捉到特殊的信号,具体的信号请查看signal手册.
           EINVAL The nfds value exceeds the RLIMIT_NOFILE value.
                    nfds的数组大小超出了RLIMIT_NOFILE
           ENOMEM There was no space to allocate file descriptor tables.
                    没有空间用于创建文件描述符表
    VERSIONS
            poll函数在2.1.23之后提供的,在老的内核中没有poll系统调用.在之前的版本可用使用select.
            
    CONFORMING TO
            poll遵循POSIX.1-2001,ppoll是linux引入的
    NOTES
            某些版本会定义非标准的常量INFTIM = -1,用于poll的timeout参数, 在glibc中不支持INFTIM常量.

  • 相关阅读:
    初识DJango框架
    web框架基础
    前端——JavaScript
    前端——css(下)
    前端——css(上)
    前端——html
    spring注解
    spring boot 详解(1)spring boot +mybatis+mysql+jsp
    spring 事务控制
    maven pom文件管理
  • 原文地址:https://www.cnblogs.com/hacker007/p/10070063.html
Copyright © 2011-2022 走看看