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

时间: 2024-10-13 21:18:11

struct pollfd的相关文章

I/O多路转接 &#160; ---- &#160; poll

一.poll poll的实现和select非常相似,只是描述fd集合的方式不同,poll使用pollfd结构而不是select的fd_set结构,其他的都差不多. 二.poll相关函数 #include <poll.h> int poll(struct pollfd *fds, nfds_t nfds, int timeout); //fds: pollfd结构体 events: 要监视的事件 revents: 已经发生的事件,  设置标志 来反映相关条件的存在 常量            

I/O多路转接之poll

不同与select使用三个位图来表示三个fdset的方式,poll使用一个 pollfd的指针实现. pollfd结构包含了要监视的event和发生的event,不再使用select"参数-值"传递的方式.同时,pollfd并没有最大数量限制(但是数量过大后性能也是会下降). 和select函数一样,poll返回后,需要轮询pollfd来获取就绪的描述符. 从上面看,select和poll都需要在返回后,通过遍历文件描述符来获取已经就绪的socket.事 实上,同时连接的大量客户端在一

多路I/O poll编写服务器

一.poll (多路复用I/O poll) 和select()函数一样,poll函数也可以执行多路I/O复用,但poll与select相比,没有像select那样构建结构体的三个数组(针对每一个条件分别有一个数组:读事件,写事件,异常),然后检查从0到nfds每个文件描述符.poll采用了一个单独的结构体pollfd数组,由fds指针指向这个组.pollfd结构体定义如下: #include <sys/poll.h> struct pollfd {int fd; //文件描述符short ev

20150218【改进信号量】IMX257实现GPIO-IRQ中断按键获取键值驱动程序

[改进信号量]IMX257实现GPIO-IRQ中断按键获取键值驱动程序 2015-02-18 李海沿 前面我们使用POLL查询方式来实现GPIO-IRQ按键中断程序 这里我们来使用信号量,让我们的驱动同时只能有一个应用程序打开. 一.首先在前面代码的基础上来一个简单的信号 1.定义一个全局的整形变量 2.在打开函数中,每次进入打开函数canopen都自减1, 3.当我们不使用时,在realease 中canopen自加1 4.这样就实现了一个简单的信号量,我们编译,测试 当我们使用两个应用程序来

20150218【改进Poll定时查询】IMX257实现GPIO-IRQ中断按键获取键值驱动程序

[改进Poll定时查询]IMX257实现GPIO-IRQ中断按键获取键值驱动程序 2015-02-18 李海沿 按键驱动程序中,如果不使用read函数中使程序休眠的,而是还是使用查询方式的话,可以使用Poll函数,来控制一定时间内,如果有按键发生,则立即返回键值. 同时,poll也可以同时监控多个(比如说按键,鼠标,等)一旦发生事件则立即返回. 我们在linux查看帮助: 从帮助中的说明得知, poll, ppoll - wait for some event on a file descrip

PX4/Pixhawk---uORB深入理解和应用

The Instructions of uORB 『PX4/Pixhawk』 ? 『软件体系结构』?『uORB』?『主题发布』?『主题订阅』 1 简介 1.1 PX4/Pixhawk的软件体系结构 ?PX4/Pixhawk的软件体系结构主要被分为四个层次,这可以让我们更好的理解PX4/Pixhawk的软件架构和运作: 应用程序的API:这个接口提供给应用程序开发人员,此API旨在尽可能的精简.扁平及隐藏其复杂性. 应用程序框架: 这是为操作基础飞行控制的默认程序集(节点). 库: 这一层包含了所

C10K问题

C10K问题: 网络服务在处理数以万计的客户端连接时,往往出现效率底下甚至完全瘫痪,这被成为C10K问题. (C10K = connection 10 kilo 问题).k 表示 kilo,即 1000 比如:kilometer(千米), kilogram(千克). 非阻塞I/O,最关键的部分是 readiness notification(when ready, then notify!) 和找出哪一个 socket 上面发生了 I/O 事件. 一般我们首先会想到用 select 来实现. i

Linux通信之poll机制分析

poll机制分析 韦东山 2009.12.10 所有的系统调用,基于都可以在它的名字前加上"sys_"前缀,这就是它在内核中对应的函数.比如系统调用open.read.write.poll,与之对应的内核函数为:sys_open.sys_read.sys_write.sys_poll. 一.内核框架: 对于系统调用poll或select,它们对应的内核函数都是sys_poll.分析sys_poll,即可理解poll机制. sys_poll函数位于fs/select.c文件中,代码如下:

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

Mosquitto 是一个IBM 开源pub/sub订阅发布协议 MQTT 的一个单机版实现(目前也只有单机版),MQTT主打轻便,比较适用于移动设备等上面,花费流量少,解析代价低.相对于XMPP等来说,简单许多. MQTT采用二进制协议,而不是XMPP的XML协议,所以一般消息甚至只需要花费2个字节的大小就可以交换信息了,对于移动开发比较有优势. IBM虽然开源了其MQTT消息协议,但是却没有开源其RSMB服务端程序,不过还好目前有比较稳定的实现可用,本文的Mosquitto是其中比较活跃的实