多路复用之poll函数

多路复用不关有select函数,还有poll函数

poll()函数

头文件:#include<sys/types.h>

       #include <poll.h>

功能:把当前的文件指针挂到等待队列

原型:intpoll(struct pollfd *fd,int numfds,int timeout)

说明:fds:用于描述需要对哪些文件的哪种类型的操作进行监控,numfds:需要监听的文件个数,即第一个参数所指向的数组中的元素数目,timeout:阻塞的超时时间,精确到毫秒级别,如果小于0,表示无限等待。

返回值:

>0:数组fds中准备好读、写或出错状态的那些socket描述符的总数量;
==0:数组fds中没有任何socket描述符准备好读、写,或出错;此时poll超时,超时时间是timeout毫秒;换句话说,如果所检测的socket描述符上没有任何事件发生的话,那么poll()函数会阻塞timeout所指定的毫秒时间长度之后返回,如果timeout==0,那么poll() 函数立即返回而不阻塞,如果timeout==INFTIM,那么poll() 函数会一直阻塞下去,直到所检测的socket描述符上的感兴趣的事件发生是才返回,如果感兴趣的事件永远不发生,那么poll()就会永远阻塞下去;
-1: poll函数调用失败,同时会自动设置全局变量errno
poll和select实现功能差不多,但poll效率高,以后要多用poll
poll()接受一个指向结构'struct pollfd'列表的指针,其中包括了你想测试的文件描述符和事件。事件由一个在结构中事件域的比特掩码确定。当前的结构在调用后将被填写并在事件发生后返回。在SVR4(可能更早的一些版本)中的 "poll.h"文件中包含了用于确定事件的一些 宏定义。事件的等待时间精确到毫秒 (但令人困惑的是等待时间的类型却是int),当等待时间为0时,poll()函数立即返回,-1则使poll()一直挂起直到一个指定事件发生。下面是pollfd的结构。
struct pollfd {
int fd; /*文件描述符*/
short events; /* 等待的需要测试事件 */
short revents; /* 实际发生了的事件,也就是返回结果 */
};

示例:

#include <fcntl.h>

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#include <string.h>

#include <time.h>

#include <errno.h>

#include <poll.h>

 

#define MAX_BUFSIZE  1024

#define IN_FILES 3

#define TIME_OUT 60000

#define MAX(a,b)    ((a > b) ? (a): (b))

 

int main(void)

{

 

    struct pollfd fds[IN_FILES];

   

    char buf[MAX_BUFSIZE];

 

    int i,res,real_read,maxfd;

 

    /*open two source files with somepermission*/

 

    fds[0].fd = 0;

 

    if((fds[1].fd =open("in1",O_RDONLY|O_NONBLOCK)) < 0)

    {

        printf("open in1 error!\n");

        return 1;

    }

 

    if((fds[2].fd =open("in2",O_RDONLY|O_NONBLOCK)) < 0)

    {

        printf("open in2 error!\n");

        return 1;

    }

 

    /*achieve the bigger one from twofiledescriptions*/

    for(i = 0; i < IN_FILES;i++)

    {

 

        fds[i].events = POLLIN;

    }

 

    while(fds[0].events || fds[1].events ||fds[2].events)

    {

 

        if(poll(fds,IN_FILES,0) < 0)

        {

            printf("Poll error or timeout\n");

            return 1;

        }

        for(i = 0;i < IN_FILES;i++)

        {

            if(fds[i].events)

            {

                memset(buf,0,MAX_BUFSIZE);

                real_read =read(fds[i].fd,buf,MAX_BUFSIZE);

                if(real_read < 0)

                {

 

                    if(errno != EAGAIN)

                    {

 

                        return 1;

                    }

                }

                else if(!real_read)

                {

                    close(fds[i].fd);

                    fds[i].events = 0;                       

                }

                else{

 

                    if(i == 0)

                    {

 

                        if((buf[0] == 'q') ||(buf[0] == 'Q'))

                        {

                            return 1;

       

                        }

                    }

                    else{

 

                        buf[real_read] = '\0';

                       printf("%s",buf);

                    }

                }

 

            }

        }

 

    }

 

    exit(0);   

}

 


  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

Echo_Anna

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值