struct pollfd
2010年04月15日 星期四 下午 03:59

int poll (struct pollfd *fds, size_t nfds , int timeout);

struct pollfd {
int fd;        /* 文件描述符 */
short events; /* 等待的事件 */
short revents; /* 实际发生了的事件 */
};

#include <sys/poll.h>
int poll(struct pollfd *ufds, unsigned int nfds, int timeout);
struct pollfd
{
int fd; /* 想查询的文件描述符. */
short int events; /* fd 上,我们感兴趣的事件*/
short int revents; /* Types of events that actually occurred. */
};

ufds 指向 struct pollfd 数组
nfds 指定 pollfd 数组元素的个数,也就是要监测几个 pollfd
http://www.linuxforum.net/forum/showflat.php?Cat=&Board=program&Number=433342&page=&view=&sb=&o=all&vc=1 EINTR分析

EINTR不是信号 是错误号 EINTR
select产生它有2个原因 被信号打断还有超时
看你的select设定了超时 而且在后面判断使用了ret<=0 这样因为超时而产生的返回值=0也被包含在里面了 所以产生了你看见EINTR的效果

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){//异常处理}

struct pollfd的更多相关文章

  1. (转载) Linux IO模式及 select、poll、epoll详解

    注:本文是对众多博客的学习和总结,可能存在理解错误.请带着怀疑的眼光,同时如果有错误希望能指出. 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案 ...

  2. linux poll函数

    poll函数与select函数差不多 函数原型: #include <poll.h> int poll(struct pollfd fd[], nfds_t nfds, int timeo ...

  3. 设备模型(device-model)之平台总线(bus),驱动(driver),设备(device)

    关于关于驱动设备模型相关概念请参考<Linux Device Drivers>等相关书籍,和内核源码目录...\Documentation\driver-model 简单来说总线(bus) ...

  4. poll机制

    使用POLL机制代替linux输入子系统(input subsystem)之按键输入和LED控制中的异步通知,实现同样的效果. 1.代码 只简单修改input_subsys_test.c, input ...

  5. Linux网络编程-IO复用技术

    IO复用是Linux中的IO模型之一,IO复用就是进程预先告诉内核需要监视的IO条件,使得内核一旦发现进程指定的一个或多个IO条件就绪,就通过进程进程处理,从而不会在单个IO上阻塞了.Linux中,提 ...

  6. c coroutine

    今天看了下云风c coroutine  代码 博客,发现 coroutine 实现原理其实还比较简单,就用户态栈切换,只需要几十行汇编,特别轻量级. 具体实现 1. 创建一个coroutine: 也就 ...

  7. Mosquitto pub/sub服务实现代码浅析-主体框架

    Mosquitto 是一个IBM 开源pub/sub订阅发布协议 MQTT 的一个单机版实现(目前也只有单机版),MQTT主打轻便,比较适用于移动设备等上面,花费流量少,解析代价低.相对于XMPP等来 ...

  8. linux c/c++

    string 字符串操作 操作数的都是 ( char * )型,操作数必须是指向字符串的指针("a"),不能是字符('a'),操作时不考虑末尾的'\0'. size_t strle ...

  9. linux网络编程

    A: osi七层: 应用层                     用 表示层                     户 会话层                     态 ************ ...

随机推荐

  1. inline修饰虚函数的问题

    虚函数是否可以内联? 一般来说,inline是编译时的行为,虚函数是在程序执行时的行为,因此编译器一般会拒绝对虚函数进行内联!

  2. URL 收录

    http://www.cnblogs.com/Olive116/p/3426957.html 地图控件 http://www.cnblogs.com/tugenhua0707/ 前端

  3. C# 与 Oracle 中 BINARY_DOUBLE数据类型查询

    Oracle 10g新增 BINARY_DOUBLE 数据类型,而.NET暂不支持这个类型,查询时需要转换为 NUMBER. eg: "SELECT RAWTOHEX(OID) AS OID ...

  4. java之JMS

    一.简介:JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进 ...

  5. blktrace btt结果分析

    对于btt的结果分析十分的困难,我和同事花了很多的时间在网上查找btt输出的每一项参数的意义,试图更好的分析bio的统计信息,但网上文章一大抄,翻来覆去就是那几篇文章. 本文中内容参考了以下网址: 1 ...

  6. yyblog2.0 数据库开发规范

    一.基础规范 (1)必须使用InnoDB存储引擎 解读:支持事务.行级锁.并发性能更好.CPU及内存缓存页优化使得资源利用率更高 (2)表字符集默认使用utf8,必要时候使用utf8mb4 解读:1. ...

  7. C# 窗体常用API函数 应用程序窗体查找

    常用的处理窗体的API函数如下(注意:API函数必须放在窗体中...): 使用C#语言,要引用DllImport,必须要添加using System.Runtime.InteropServices命名 ...

  8. c# 数据集调试工具插件

    DataSetSpySetup,调试期查看dataset数据集的记录内容, Debug DataSet

  9. ansible debug

    <demoredis_redis_1> ESTABLISH DOCKER CONNECTION FOR USER: ?<demoredis_redis_1> EXEC ['/u ...

  10. 多产生半成品工单的问题 修改带SO的半成品工单无法分配给SO的问题的

    原因:验货及VIP带SO的半成品MO无法分配给对应的SO问题, 解决: SELECT SL.ENTERPRISE , SL.ENGINE_ID , SL.SITEID , ML.MO_ID || '_ ...