您的位置:首页 > 其它

poll函数

2015-08-28 21:46 134 查看
函数原型
#include<poll.h>
int poll(struct pollfd fdarray[],nfds_t nfds, int timeout);
		返回值:准备就绪的描述符数目;若是超时,返回0;若是出错,返回-1
第一个参数 pollfd 结构体定义如下:
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 是否已经无效。

最后一个参数 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 是否阻塞没有任何影响。



poll 使用样式示例

代码:

#include<poll.h>                                
#include<fcntl.h>                                
#include<sys/time.h>
#include<stdio.h>
#include<stdlib.h>                        
                                
int main (int argc, char **argv)
{                               
        int sfd1, sfd2, sfd3;   

        struct pollfd Events [3];
        int retval;              
        char buff [256];         
        int readcnt;             
        sfd1 = open ("/dev/ttyS1", O_RDWR | O_NOCTTY);
        sfd2 = open ("/dev/ttyS2", O_RDWR | O_NOCTTY);
        sfd3 = open ("/dev/ttyS3", O_RDWR | O_NOCTTY);
        ...
        /*各个串行环境设定程序*/
        ...                     
        memset (Event, 0, sizeof(Events));

        Event[0].fd = sfd1;
        Event[0].events = POLLIN | POLLERR;     /*关心读取和出错事件*/

        Event[1].fd = sfd2;
        Event[1].events = POLLIN | POLLERR;     /*关心读取和出错事件*/

        Event[2].fd = sfd3;
        Event[2].events = POLLIN | POLLERR;     /*关心读取和出错事件*/
        while (1) {
                /*等待事件*/
                retval = poll ((struct pollfd *)&Events, 3, 5000);
                if (retval < 0) {                                 
                        perror ("poll");
                        exit (EXIT_FAILURE);
                }
                if (retval == 0) {
                        prinntf ("no data in 5 seconds.\n");
                        continue;
                }

                for (i = 0; i < 3; i++) {
                        /*检查错误*/
                        if (Events[i].revents & POLLERR) {
                                printf ("device error!\n");
                                exit (EXIT_FAILURE);
                        }

                        /*检查是否存在传递的数据(可读)*/
                        if (Events[i].revents & POLLIN) {
                                readcnt = read (Events[i].fd, buff, 256);
                                write (Events[i].fd, buff, readcnt);
                        }
                }
        }

        close (sfd1);
        close (sfd2);
        colse (sfd3);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: