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. TortoiseSVN比较工具设置为BeyondCompare 4

    打开TortoiseSVN的Setting,选择左边的Diff Viewer 设置如下: "D:\Program Files\Beyond Compare 4\BComp.exe" ...

  2. virtualenv基本使用

    win 安装 virtualenv pip3 install virtualenv 创建虚拟环境 virtualenv env1 进入虚拟环境 env1/Scripts/activate 退出虚拟环境 ...

  3. erlang的一些系统限制修改

    atom个数限制 +t xxx 进程数限制 +P xxxx ets表个数限制 +e xxx ports个数限制 +Q xxxx 查看限制 string:tokens(binary_to_list(er ...

  4. 学习OCI编程

    转自:http://kulong0105.blog.163.com/blog/static/174406191201162145944574/ 最近公司做的一个项目,要处理海量数据,数据是存放在Ora ...

  5. week2--线性表

    一.PTA实验作业 题目1:顺序表删除重复元素(6-3) 设计思路 代码截图 PTA提交列表说明 编译错误:写'->'符号的时候总是漏掉'>'; 写'!='符号的时候漏写'!'; 解决方法 ...

  6. apache make

    https://jingyan.baidu.com/article/7e4409533d7f0f2fc0e2ef91.html 1. apr apr-util http://archive.apach ...

  7. 汇编_指令_SHL、SHR、SAL、SAR、ROL、ROR、RCL、RCR

    ;SHL(Shift Left):      逻辑左移 ;SHR(Shift Right):      逻辑右移 ;SAL(Shift Arithmetic Left): 算术左移 ;SAR(Shif ...

  8. java中的DAO设计模式

    创建数据库和表 sql语句: DROP TABLE IF EXISTS product; CREATE TABLE product( product_id varchar(20) NOT NULL, ...

  9. JSP自定义业务标签

    自定义标签: package cn.hv.tag; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; ...

  10. JavaScript之深拷贝&浅拷贝

    深拷贝&浅拷贝,说起来都明白,但是说不出所以然.今天就系统的整理下思绪,一点点的将其分析出所以然 废话不多说 浅拷贝 简单的说就是一个值引用,学生时代接触过编程的人都应该了解过指针,浅拷贝可以 ...