POLL返回值详解

合集下载

poll 函数详解 -回复

poll 函数详解 -回复

poll 函数详解-回复关于[poll 函数详解]的主题,我将以一步一步的方式回答并解释:第一步:什么是poll 函数?poll 函数是一个在计算机编程中经常使用的系统调用。

它被用于检查一组文件描述符(file descriptor)的状态,以确定是否可以对它们进行读取、写入或者是否发生了错误。

poll 函数是异步I/O 操作的一种方式,它可以用于监控多个文件描述符的状态变化,从而避免使用多个阻塞式I/O 操作。

第二步:poll 函数的参数及返回值是什么?poll 函数的原型如下:cint poll(struct pollfd fds[], nfds_t nfds, int timeout);其中,`struct pollfd` 是一个结构体类型,用于描述需要监控的文件描述符及其事件。

`nfds_t` 是一个整数类型,表示需要监控的文件描述符的数量。

`timeout` 是一个整数类型,用于设置超时时间。

返回值是一个整数类型的数值,表示有多少个文件描述符满足了监控的事件,其中包括有事件可读、有事件可写和发生了错误。

第三步:如何使用poll 函数?使用poll 函数需要以下几个步骤:1. 创建一个`struct pollfd` 的数组,并填充每个结构体中的字段。

2. 调用poll 函数,将该结构体数组、文件描述符的数量以及超时时间作为参数传入。

3. 检查poll 函数的返回值,以确定哪些文件描述符发生了事件。

4. 对返回的文件描述符进行相应的操作,例如读取数据或写入数据。

第四步:如何填充`struct pollfd` 结构体的字段?`struct pollfd` 结构体的定义如下:cstruct pollfd {int fd; 文件描述符short events; 指定需要监控的事件short revents; 实际发生了哪些事件};其中,`fd` 字段表示需要监控的文件描述符;`events` 字段是一个位掩码,用于指定需要监控的事件,可以是`POLLIN`(可读事件),`POLLOUT`(可写事件)或其他事件;`revents` 字段表示实际发生了哪些事件,由操作系统填充。

poll机制的分析理解

poll机制的分析理解

声明:看如下文字,最好对应内核源码2.6.22.6一步一步对应着看,效果最好。

首先,应用程序函数调用驱动程序对应的函数,都是先通过调用:系统调用接口(sys 前缀)。

当然poll函数也是一样的。

我们从系统调用来一直往下分析:sys_poll函数位于select.c文件中。

应用层传递三个参数fds,nfds,timeoutFds:其实我们定义的是一个结构体数组,pollfd结构体(在poll.h文件)包含,三个数据:fd,events,revents,其中fd为文件描述符。

Events为等待的事件(如等待中断标志)值可为这些POLLIN/POLLRDNORM(可读)、POLLOUT/POLLWRNORM(可写)、POLLERR(出错) revents:实际发生的事件Nfds:要监视的文件描述符的个数Timeout:超时时间(毫秒级的)(可理解成在无任何操作时超时时间内这段时间休眠),网上说如果timeout的值为-1,poll就永远不会超时。

如果整数值为32个比特,那么最大的超时周期大约为30分钟,如果值为0则立即返回。

在sys_poll函数中先对timeout稍作处理,接着将处理过的timeout传入do_sys_poll函数中,在此函数中做两件事:第一用poll_initwait(&table);函数初始化struct poll_wqueues table;结构体。

定义table的结构体为poll_wqueues在它的内部有另外一个结构体为poll_table_entry,这个结构体就是包含了驱动程序poll函数中的poll_wait(file, &button_waitq, wait)函数中传进来的三个参数,初始化完三个参数后,在poll_initwait函数中①用函数指针指向了poll_wait函数②_pollwait函数中初始化等待队列为空的双向循环链表并将当前进程加入等待队列init_waitqueue_entry(&entry->wait, current);Current:是内核的一个全局变量,用来记录当前进程,内核对于每一个进程,在内核空间都有一个对应的结构体struct task_struct,而current指针就指向当前运行的那个进程的task_struct结构体,你可以通过current指针来获取当前进程的pid和进程的名字(current->pid, current->comm)然后定义一个等待队列头(static DECLARE_WAIT_QUEUE_HEAD(button_waitq);)加入等待队列即将进程加入等待队列头(Linux内核的等待队列是以双向循环链表为基础数据结构,与进程调度机制紧密结合,能够用于实现核心的异步事件通知机制。

poll和select

poll和select

详述socket编程之select()和poll()函数select()函数和poll()函数均是主要用来处理多路I/O复用的情况。

比如一个服务器既想等待输入终端到来,又想等待若干个套接字有客户请求到达,这时候就需要借助select或者poll函数了。

(一)select()函数、原型如下:1int select(int fdsp1, fd_set *readfds, fd_set *writefds, fd_set *errorfds, const struct timeval *timeout);各个参数含义如下:int fdsp1:最大描述符值+ 1fd_set *readfds:对可读感兴趣的描述符集fd_set *writefds:对可写感兴趣的描述符集fd_set *errorfds:对出错感兴趣的描述符集struct timeval *timeout:超时时间select函数会在发生以下情况时返回:1readfds集合中有描述符可读2writefds集合中有描述符可写3errorfds集合中有描述符遇到错误条件指定的超时时间timeout到了过去,一个fd_set通常只能包含<32的fd(文件描述字),因为fd_set其实只用了一个32位矢量来表示fd;现在,UNIX系统通常会在头文件中定义常量FD_SETSIZE,它是数据类型fd_set的描述字数量,其值通常是1024,这样就能表示<1024的fd问题2:当select返回的时候,如何知道是哪个fd发生变化了,fs_set各个位发生了什么变化?当select返回的时候,rset位都将被置0,除了那些有变化的fd位..假设有两个文件描述符,值分别是7和9,被放在readfds中。

当select()返回时,如果7仍然在set中,则这个文件描述符已经准备好被读取而不会阻塞。

如果9已经不在set中,则读取它将可能会阻塞(我说可能是因为数据可能正好在select返回后就可用,这种情况下,下一次调用select()将返回文件描述符准备好读取)。

poll函数详解以及实例分析

poll函数详解以及实例分析

poll函数详解以及实例分析1、基本知识 poll的机制与select类似,与select在本质上没有多⼤差别,管理多个描述符也是进⾏轮询,根据描述符的状态进⾏处理,但是poll没有最⼤⽂件描述符数量的限制。

poll和select同样存在⼀个缺点就是,包含⼤量⽂件描述符的数组被整体复制于⽤户态和内核的地址空间之间,⽽不论这些⽂件描述符是否就绪,它的开销随着⽂件描述符数量的增加⽽线性增⼤。

2、poll函数 函数格式如下所⽰:# include <poll.h>int poll ( struct pollfd * fds, unsigned int nfds, int timeout);pollfd结构体定义如下:struct pollfd {int fd; /* ⽂件描述符 */short events; /* 等待的事件 */short revents; /* 实际发⽣了的事件 */} ; 每⼀个pollfd结构体指定了⼀个被监视的⽂件描述符,可以传递多个结构体,指⽰poll()监视多个⽂件描述符。

每个结构体的events域是监视该⽂件描述符的事件掩码,由⽤户来设置这个域。

revents域是⽂件描述符的操作结果事件掩码,内核在调⽤返回时设置这个域。

events 域中请求的任何事件都可能在revents域中返回。

合法的事件如下: POLLIN 有数据可读。

POLLRDNORM 有普通数据可读。

POLLRDBAND 有优先数据可读。

POLLPRI 有紧迫数据可读。

POLLOUT 写数据不会导致阻塞。

POLLWRNORM 写普通数据不会导致阻塞。

POLLWRBAND 写优先数据不会导致阻塞。

POLLMSGSIGPOLL 消息可⽤。

此外,revents域中还可能返回下列事件: POLLER 指定的⽂件描述符发⽣错误。

POLLHUP 指定的⽂件描述符挂起事件。

POLLNVAL 指定的⽂件描述符⾮法。

linux下select 和 poll的用法

linux下select 和 poll的用法

linux下select 和poll的用法select()函数的作用系统调用select和poll的后端实现,用这两个系统调用来查询设备是否可读写,或是否处于某种状态。

如果poll为空,则驱动设备会被认为即可读又可写,返回值是一个状态掩码如何使用select()函数?select()函数的接口主要是建立在一种叫'fd_set'类型的基础上。

它('fd_set') 是一组文件描述符(fd)的集合。

由于fd_set类型的长度在不同平台上不同,因此应该用一组标准的宏定义来处理此类变量:fd_set set;FD_ZERO(&set); /* 将set清零*/FD_SET(fd, &set); /* 将fd加入set */FD_CLR(fd, &set); /* 将fd从set中清除*/FD_ISSET(fd, &set); /* 如果fd在set中则真*/在过去,一个fd_set通常只能包含少于等于32个文件描述符,因为fd_set其实只用了一个int的比特矢量来实现,在大多数情况下,检查fd_set能包括任意值的文件描述符是系统的责任,但确定你的fd_set到底能放多少有时你应该检查/修改宏FD_SETSIZE的值。

*这个值是系统相关的*,同时检查你的系统中的select() 的man手册。

有一些系统对多于1024个文件描述符的支持有问题。

[译者注:Linux就是这样的系统!你会发现sizeof(fd_set)的结果是128(*8 = FD_SETSIZE=1024)尽管很少你会遇到这种情况。

]select的基本接口十分简单:int select(int nfds, fd_set *readset, fd_set *writeset,fd_set *exceptset, struct timeval *timeout);其中:nfds需要检查的文件描述符个数,数值应该比是三组fd_set中最大数更大,而不是实际文件描述符的总数。

linux中select、poll、epoll原理详解

linux中select、poll、epoll原理详解

linux中select、poll、epoll原理详解目录1. 引言1.1 背景和意义1.2 结构概述1.3 目的2. select原理详解2.1 基本概念2.2 使用方法2.3 应用场景3. poll原理详解3.1 基本概念3.2 使用方法3.3 应用场景4. epoll原理详解4.1 基本概念4.2 使用方法4.3 应用场景5. 结论5.1 对比分析选择合适的IO多路复用器5.2 总结与展望引言1.1 背景和意义在计算机网络编程中,同时监听多个文件描述符的可读、可写和异常事件是一项基本任务。

为了高效地处理这些事件,Linux提供了三种IO多路复用器:select、poll和epoll。

它们允许程序通过一次系统调用就能同时监听多个文件描述符,并在有可读、可写或异常事件发生时进行相应的处理。

使用IO多路复用器可以避免使用阻塞式IO或者轮询方式造成的性能损失,提高了程序的效率和响应速度。

尤其对于具有大量并发连接的服务器程序来说,选择合适的IO多路复用器可以极大地提升系统性能。

1.2 结构概述本文将详细解析Linux中三种IO多路复用器的原理和使用方法,包括select、poll和epoll。

对于每种IO多路复用器,我们将介绍其基本概念、使用方法以及适用场景。

通过深入理解这些IO多路复用器的工作原理,我们可以更好地掌握它们的特点及优缺点,并根据实际需求选择合适的方式来进行网络编程。

1.3 目的本文旨在帮助读者全面了解Linux中select、poll和epoll的原理和使用方法,以及它们在网络编程中的应用场景。

在深入理解这些IO多路复用器的基础上,读者可以根据实际需求灵活选择合适的IO多路复用器,提升程序的性能和可扩展性。

在接下来的文章中,我们将逐一介绍select、poll和epoll的原理详解、使用方法和应用场景,并进行对比分析,最后总结归纳各种IO多路复用器的特点及适用情况。

2. select原理详解2.1 基本概念在Linux系统中,select是一种常用的I/O多路复用机制,它可以监视多个文件描述符的状态是否满足某种条件,在有一或多个文件描述符就绪时通知进程进行相应的 I/O操作。

poll函数详解

poll函数详解

poll函数详解题目:poll函数详解段落一:poll函数是一个系统调用,用于在多个文件描述符上进行轮询操作,以确定是否有事件发生。

它可以用于实现高效的事件驱动程序。

该函数在Linux系统中被广泛使用。

段落二:poll函数的原型为int poll(struct pollfd *fds, nfds_t nfds, int timeout)。

其中,fds是一个指向pollfd结构体数组的指针,每个结构体描述一个文件描述符及其关注的事件;nfds是fds数组的大小;timeout是等待事件发生的超时时间。

段落三:在使用poll函数之前,我们需要初始化pollfd结构体数组。

每个结构体中的fd成员表示要监视的文件描述符,events成员表示关注的事件类型,revents成员则是poll函数返回时指示发生的事件类型。

段落四:调用poll函数后,它将阻塞等待直到有事件发生或超时。

如果有事件发生,poll函数将返回一个正整数,表示有事件发生的文件描述符的数量。

此时,我们可以通过遍历pollfd结构体数组,检查revents成员来确定具体是哪些文件描述符的事件发生了。

段落五:poll函数的返回值还可以有其他几种情况。

如果超时时间到达而没有事件发生,则返回0。

如果调用过程中被信号中断,则返回-1,并且设置errno为EINTR。

如果传入的参数有误,则返回-1,并且设置errno为EINVAL。

段落六:值得注意的是,poll函数与select函数类似,但poll函数没有最大文件描述符限制,并且可以提供更加精确的事件类型检测。

因此,在需要同时监视大量文件描述符或需要更灵活的事件检测时,poll 函数是一个更好的选择。

段落七:总结一下,poll函数是一个用于在多个文件描述符上进行轮询操作的系统调用。

它的使用需要初始化pollfd结构体数组,并设置关注的事件类型。

调用poll函数后,它将等待事件发生或超时,并返回有事件发生的文件描述符数量。

Linux驱动之poll机制的理解与简单使用

Linux驱动之poll机制的理解与简单使用

Linux驱动之poll机制的理解与简单使⽤之前在中编写的驱动程序,如果没有按键按下。

read函数是永远没有返回值的,现在想要做到即使没有按键按下,在⼀定时间之后也会有返回值。

要做到这种功能,可以使⽤poll机制。

分以下⼏部来介绍poll机制1、poll机制的使⽤,编写测试程序2、poll机制的调⽤过程分析3、poll机制的驱动编写1、poll机制的使⽤,编写测试程序。

直接看到测试程序的代码。

#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <stdio.h>#include <poll.h>/**usage ./buttonstest*/int main(int argc, char **argv){int fd;char* filename="dev/buttons";unsigned char key_val;unsigned long cnt=0;int ret;struct pollfd *key_fds;//定义⼀个pollfd结构体key_fdsfd = open(filename, O_RDWR);//打开dev/firstdrv设备⽂件if (fd < 0)//⼩于0说明没有成功{printf("error, can't open %s\n", filename);return0;}if(argc !=1){printf("Usage : %s ",argv[0]);return0;}key_fds ->fd = fd;//⽂件key_fds->events = POLLIN;//poll直接返回需要的条件while(1){ret = poll(key_fds, 1, 5000);//调⽤sys_poll系统调⽤,如果5S内没有产⽣POLLIN事件,那么返回,如果有POLLIN事件,直接返回if(!ret){printf("time out\n");}else{if(key_fds->revents==POLLIN)//如果返回的值是POLLIN,说明有数据POLL才返回的{read(fd, &key_val, 1); //读取按键值printf("key_val: %x\n",key_val);//打印}}}return0;}从代码可以看出,相⽐较第三个测试程序third_test。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

POLL返回值详解
和select() 函数一样,poll() 函数也可以用于执行多路复用I/O 。

但poll() 与slect()相比,用起来更加直观容易。

使用该函数,需要包含#include <poll.h>文件,实际上最终包含的是<sys/poll.h>文件,poll.h 里的内容也就是#include <sys/poll.h> 。

函数的原型:
引用
#include <poll.h>
extern int poll (struct pollfd*__fds,nfds_t__nfds,int__timeout);
poll() 没有像select() 构建fd_set 结构体的3 个数组( 针对每个条件分别有一个数组:可读性、可写性和错误条件) ,然后检查从0 到nfds 每个文件描述符。

第一个参数pollfd 结构体定义如下:
引用
/* Data structure describing a polling request. */
struct pollfd
{
int fd; /* poll 的文件描述符. */
short int events; /* fd 上感兴趣的事件(等待的事件). */
short int revents; /* fd 上实际发生的事件. */
};
fd成员表示感兴趣的,且打开了的文件描述符;
events成员是位掩码,用于指定针对这个文件描述符感兴趣的事件;revents成员是位掩码,用于指定当poll 返回时,在该文件描述符上已经发生了哪些事情。

events 和revents 结合下列常数值(宏)指定即将唤醒的事件或调查已结束的poll() 函数被唤醒的原因,这些宏常数如下:
∙POLLIN
events 中使用该宏常数,能够在折本文件的可读情况下,结束poll() 函数。

相反,revents 上使用该宏常数,在检查poll() 函数结束后,可依此判断设备文件是否处于可读状态(即使消息长度是0)。

∙POLLPRI
在events 域中使用该宏常数,能够在设备文件的高优先级数据读取状态下,结束poll() 函数。

相反,revents 上使用该宏常数,在检查poll() 函数结束后,
可依此判断设备文件是否处于可读高优先级数据的状态(即使消息长度是0)。

该宏常数用于处理网络信息包(packet) 的数据传递。

∙POLLOUT
在events 域中使用该宏常数,能够在设备文件的写入状态下,结束poll() 函数。

相反,revents 域上使用该宏常数,在检查poll() 结束后,可依此判断设备文件是否处于可写状态。

∙POLLERR
在events 域中使用该宏常数,能够在设备文件上发生错误时,结束poll()函数。

相反,revents域上使用该宏函数,在检查poll()函数结束后,可依此判断设备文件是否出错。

∙POLLHUP
在events域中使用该宏常数,能够在设备文件中发生hungup时,结束poll() 函数。

相反,在检查poll() 结束后,可依此判断设备文件是否发生hungup 。

∙POLLNVAL
在events 域中使用该宏函数,能够在文件描述符的值无效时,结束poll() 。

相反,在revents 域上使用该宏函数时,在检查poll() 函数后,文件描述符是否有效。

可用于处理网络信息时,检查socket handler 是否已经无效。

和select 一样,最后一个参数timeout 指定poll() 将在超时前等待一个事件多长事件。

这里有3 种情况:
1) timeout 为-1
这会造成poll 永远等待。

poll() 只有在一个描述符就绪时返回,或者在调用进程捕捉到信号时返回(在这里,poll 返回-1),并且设置errno 值为EINTR 。

-1 可以用宏定义常量INFTIM来代替(在pth.h 中有定义) 。

2) timeout 等于0
在这种情况下,测试所有的描述符,并且poll() 立刻返回。

这允许在poll 中没有阻塞的情况下找出多个文件描述符的状态。

3) time > 0
这将以毫秒为单位指定timeout 的超时周期。

poll() 只有在超时到期时返回,除非一个描述符变为就绪,在这种情况下,它立刻返回。

如果超时周期到齐,poll() 返回0。

这里也可能会因为某个信号而中断该等待。

和select 一样,文件描述符是否阻塞对poll 是否阻塞没有任何影响。

相关文档
最新文档