IO复用之poll

本文介绍了Poll函数的工作原理,它用于监控多个文件描述符的读写就绪状态,避免了Select函数的最大文件描述符限制。Poll使用结构体数组管理文件描述符,支持大数量的句柄,但存在性能问题,如轮询开销和大量数据复制。示例代码展示了如何使用Poll监控标准输入的读就绪事件。
摘要由CSDN通过智能技术生成

poll函数工作原理与select函数类似,也是监管一系列的文件描述符,阻塞的去轮询看这些文件描述符是否可读/可写/异常,再去调用io函数读写。

#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);

struct pollfd {
   int   fd;         /* 文件描述符 */
   short events;     /* 注册的事件 */
   short revents;    /* 实际发生的事件,由内核填充 */
};

(1)fds:指向一个结构体数组的第0个元素的指针,每个数组元素都是一个struct pollfd结构,
它指向所有我们感兴趣的文件描述符上发生的事件
(2)nfds:表示fds结构体数组的长度 
(3)timeout:表示poll函数的超时时间,单位是毫秒 
返回值: 
(1)小于0,表示出错 
(2)等于0,表示poll函数等待超时 
(3)大于0,表示poll由于监听的文件描述符就绪返回,并且返回结果就是就绪的文件描述符的个数。

poll支持的事件类型如下图所示

 

 特点分析:


1、优点
(1)poll不要求开发者计算最大文件描述符加一的大小。 
(2)poll在应付大数目的文件描述符的时候速度更快,相比于select。 
(3)它没有最大连接数的限制,原因是它是基于链表来存储的。 
(4)在调用函数时,只需要对参数进行一次设置就好了
 
2、缺点
(1)大量的句柄数据结构被整体复制于用户态和内核地址空间之间,产生巨大的开销;

(2)poll采用轮询的方式扫描文件描述符,文件描述符数量越多,性能越差;
(3)同时连接的大量客户端在一时刻可能只有很少的就绪状态,因此随着监视的描述符数量的增长,其效率也会线性下降

(4)返回的是含有整个句柄的数组,应用程序需要遍历整个数组才能发现哪些句柄发生了事件;

(5)触发方式是水平触发,应用程序如果没有完成对一个已经就绪的文件描述符进行IO操作,那么之后每次select调用还是会将这些文件描述符通知进程。

示例代码

#include<poll.h>
#include<signal.h>
#include<iostream>
#include <unistd.h>
using namespace std;
int main()
{
        /*第一步 poll开始监听之前要知道要监管哪些套接字*/
            struct pollfd fds[1];
            fds[0].fd=0;
            fds[0].events=POLL_IN;
            fds[0].revents=POLL_IN;
            
        /*第二步 poll开始工作 阻塞的轮询看监管的套接字是否就绪*/
 
          int ret=poll(fds,1,5000);
 
        /*第三步  poll完成工作  有套接字就绪或者时间超时返回*/
        if(ret<0)
            {
                cout<<"error"<<endl;
            }
        else if(ret==0)
            {
                cout<<"time out"<<endl;
            }
        else
        {
            if(fds[0].revents==POLL_IN)
                {
                    char message[10];
                    read(fds[0].fd,message,sizeof(message));
                    cout<<message<<endl;
                }   
        }
}

 

上面的代码实现的功能就是把标准输入(即文件描述符为0)纳入poll的监管,然后poll在5s内阻塞的轮询看是否有读就绪事件。如果有的话就返回对其进行处理,如果超时或者出错的话也返回

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值