Linux poll

原创 2017年03月19日 21:42:24
poll()函数:这个函数是某些Unix系统提供的用于执行与select()函数同等功能的函数,下面是这个函数的声明:

#include <poll.h>
int poll(struct pollfd fds[], nfds_t nfds, int timeout);

参数说明:
fds:是一个struct pollfd结构类型的数组,用于存放需要检测其状态的Socket描述符;每当调用这个函数之后,系统不会清空这个数组,操作起来比较方便;特别是对于socket连接比较多的情况下,在一定程度上可以提高处理的效率;这一点与select()函数不同,调用select()函数之后,select()函数会清空它所检测的socket描述符集合,导致每次调用select()之前都必须把socket描述符重新加入到待检测的集合中;因此,select()函数适合于只检测一个socket描述符的情况,而poll()函数适合于大量socket描述符的情况;

nfds:nfds_t类型的参数,用于标记数组fds中的结构体元素的总数量;

timeout:是poll函数调用阻塞的时间,单位:毫秒;

返回值:
>0:数组fds中准备好读、写或出错状态的那些socket描述符的总数量;

==0:数组fds中没有任何socket描述符准备好读、写,或出错;此时poll超时,超时时间是timeout毫秒;换句话说,如果所检测的socket描述符上没有任何事件发生的话,那么poll()函数会阻塞timeout所指定的毫秒时间长度之后返回,如果timeout==0,那么poll() 函数立即返回而不阻塞,如果timeout==INFTIM,那么poll() 函数会一直阻塞下去,直到所检测的socket描述符上的感兴趣的事件发生是才返回,如果感兴趣的事件永远不发生,那么poll()就会永远阻塞下去;

-1:  poll函数调用失败,同时会自动设置全局变量errno;

如果待检测的socket描述符为负值,则对这个描述符的检测就会被忽略,也就是不会对成员变量events进行检测,在events上注册的事件也会被忽略,poll()函数返回的时候,会把成员变量revents设置为0,表示没有事件发生;

另外,poll() 函数不会受到socket描述符上的O_NDELAY标记和O_NONBLOCK标记的影响和制约,也就是说,不管socket是阻塞的还是非阻塞的,poll()函数都不会收到影响;而select()函数则不同,select()函数会受到O_NDELAY标记和O_NONBLOCK标记的影响,如果socket是阻塞的socket,则调用select()跟不调用select()时的效果是一样的,socket仍然是阻塞式TCP通讯,相反,如果socket是非阻塞的socket,那么调用select()时就可以实现非阻塞式TCP通讯;

所以poll() 函数的功能和返回值的含义与 select() 函数的功能和返回值的含义是完全一样的,两者之间的差别就是内部实现方式不一样,select()函数基本上可以在所有支持文件描述符操作的系统平台上运行(如:Linux 、Unix 、Windows、MacOS等),可移植性好,而poll()函数则只有个别的的操作系统提供支持(如:SunOS、Solaris、AIX、HP提供支持,但是Linux不提供支持),可移植性差;

strust pollfd结构说明:
typedef struct pollfd {
        int fd;                               /* 需要被检测或选择的文件描述符*/
        short events;                   /* 对文件描述符fd上感兴趣的事件 */
        short revents;                  /* 文件描述符fd上当前实际发生的事件*/
} pollfd_t;

typedef unsigned long   nfds_t;

经常检测的事件标记: POLLIN/POLLRDNORM(可读)、POLLOUT/POLLWRNORM(可写)、POLLERR(出错)

如果是对一个描述符上的多个事件感兴趣的话,可以把这些常量标记之间进行按位或运算就可以了;

比如:对socket描述符fd上的读、写、异常事件感兴趣,就可以这样做:struct pollfd  fds;

fds[nIndex].events=POLLIN | POLLOUT | POLLERR;

当 poll()函数返回时,要判断所检测的socket描述符上发生的事件,可以这样做: struct pollfd  fds;

检测可读TCP连接请求:
if((fds[nIndex].revents & POLLIN) == POLLIN){//接收数据/调用accept()接收连接请求}

检测可写:
if((fds[nIndex].revents & POLLOUT) == POLLOUT){//发送数据}

检测异常:

if((fds[nIndex].revents & POLLERR) == POLLERR){//异常处理} 



整理自网络

Linux网络编程——I/O复用之poll函数

一、回顾前面的select select优点: 目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点 select缺点: 1.每次调用 select(),都...
  • lianghe_work
  • lianghe_work
  • 2015年06月17日 15:09
  • 5812

Linux - poll()

linux man中`poll`的翻译,`poll`在设计上解决了`select`可监听描述符的个数限制,但在一些系统中兼容性并不是很好,因此还是建议使用`select`来实现简单`socket`应用...
  • myloveqingmu
  • myloveqingmu
  • 2016年05月21日 19:27
  • 731

Linux Poll 使用方法和实现

Linux socket之四:使用POLL机制处理多连接         使用select函数可以处理socket多连接的问题(select的用法参见:http://blog.csdn....
  • zhuxiaoping54532
  • zhuxiaoping54532
  • 2016年06月17日 17:34
  • 1805

linux字符驱动之poll机制按键驱动

在上一节中,我们讲解了如何自动创建设备节点,实现一个中断方式的按键驱动。虽然中断式的驱动,效率是蛮高的,但是大家有没有发现,应用程序的死循环里的读函数是一直在读的;在实际的应用场所里,有没有那么一种情...
  • lwj103862095
  • lwj103862095
  • 2013年12月24日 20:58
  • 7843

Linux内核:poll机制

在编写驱动程序的过程当中我们可以使用poll机制来非阻塞的打开我们的设备文件,我们知道,在之前我们编写CC1100的驱动程序以及倒车雷达的驱动程序的时候,在read函数中都有用到过wait_event...
  • JansonZhe
  • JansonZhe
  • 2015年09月19日 16:20
  • 3027

linux下select 和 poll的用法

select()函数的作用      系统调用select和poll的后端实现,用这两个系统调用来查询设备是否可读写,或是否处于某种状态。如果poll为空,则驱动设备会被认为即可读又可写,返回值是一个...
  • linrix
  • linrix
  • 2007年08月02日 15:44
  • 8040

Linux网络编程——tcp并发服务器(poll实现)

想详细彻底地了解poll或看懂下面的代码请参考《Linux网络编程——I/O复用之poll函数》 代码: #include #include #include #include #incl...
  • lianghe_work
  • lianghe_work
  • 2015年06月17日 17:13
  • 3064

浅析 Linux poll 机制

在用户空间应用程序向驱动程序请求数据时,有以下几种方式: 1、不断查询,条件不满足的情况下就是死循环,非常耗cpu 2、休眠唤醒的方式,如果条件不满足,应用程序则一直睡眠下去 3、poll机制,如果条...
  • lizuobin2
  • lizuobin2
  • 2016年09月29日 21:05
  • 1170

Linux Poll函数初级实例

网络编程
  • XW370168409
  • XW370168409
  • 2016年12月01日 22:36
  • 392

linux poll 使用简单例子

可以监听多个客户端,代码比select简洁。直接上服务端代码,测试可以用telnet。  #include #include #include #include #include #inc...
  • dongdongbusi
  • dongdongbusi
  • 2015年01月23日 23:09
  • 810
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux poll
举报原因:
原因补充:

(最多只允许输入30个字)