ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

【Linux】14.IO多路转接之详解poll

2022-02-21 12:32:43  阅读:172  来源: 互联网

标签:14 IO 描述符 pf 事件 监控 Linux poll buf


目录

poll:地位不如select,因为select可以跨平台,性能又不如epoll

接口函数

int poll(struct pollfd* fds, nfds_t nfds, int timeout);

fds:事件结构数组,poll函数是通过用户传入的事件结构数组进行监控的,也是轮询监控的方式
        如果要监控一个文件描述符,则组织一个事件结构,传递给poll
        如果要监控多个文件描述符,则组织多个事件结构,放到数组当中,传递给poll
时间结构:struct pollfd{…}

struct pollfd
{
	int fd;
	short events;
	short revents;
}

fd:待要监控的文件描述符
events:关心当中文件描述符产生什么事件(可读、可写、异常)
              POLLIN:可读事件
              POLLOUT:可写事件
              如果既关心可读事件也关心可写时间,则将POLLIN | POLLOUT

revents:在poll监控文件描述符的时候,真实产生的事件
               poll在监控的过程当中,文件描述符发生了什么事件,就将该事件放到revents当中

在定义pollfd事件结构体的时候,不需要用户进行初始化,由poll函数进行初始化

小结:
(1)poll函数引入了事件结构数组的方式,对需要内核监控的文件描述符个数是没有限制了。
(2)poll在监控事件结构数组的时候,也是采用轮询遍历的方式进行监控,随着监控的事件结构(文件描述符)的增多,监控轮询效率下降。
(3)用户如果关心一个文件描述符的多种事件(可读、可写、异常),可以直接在同一个事件结构的结构体当中表示,不需要像select一样,添加到不同的事件集合当中去。

nfds:事件结构数组当中有效元素的个数,用来指导poll函数,轮询遍历的范围
eg:struct pollfd arr[10];
        arr[0].fd = 0;
        arr[0].events = POLLIN;

        则:nfds = 1;

timeout:超时时间
               > 0 :带有超时时间的监控,单位:毫秒
               0 :非阻塞的监控方式
               < 0 :阻塞监控的方式

注意区分poll与select的超时时间的传参方式
select的超时时间参数是struct timeval * timeout,需要传入timeval结构体地址。
poll的超时时间参数是int timeout,只需要传入数字即可。

返回值:> 0 :监控成功,返回就绪的文件描述符个数
== 0 :监控超时
< 0 :监控出错

poll的优缺点

优点:
(1)引入了事件结构的方式,用户不需要将关心的事件添加到不同的事件集合当中去。
(2)引用了事件结构的方式,对监控的文件描述符的个数不再限制。
(3)针对和select对比之后,当一次监控成功之后,下一次再次进行监控的时候,不需要重新添加。
缺点:
(1)与select一样也是采用轮询遍历的策略,随着监控的文件描述符增多,轮询效率会下降。
(2)poll不支持跨平台,只能在linux操作系统下使用
(3)在调用poll函数的时候,会将用户组织的事件结构数组,拷贝到内核空间,监控成功之后,会将事件结构数组从内核空间拷贝到用户空间,这个举动比较耗费性能。

poll阻塞监控代码

#include <stdio.h>
#include <unistd.h>
#include <poll.h>

//阻塞  监控 0 号文件描述符

int main()
{
    struct pollfd pf;
    pf.fd = 0;
    pf.events = POLLIN; // 关心可读事件

    poll(&pf, 1, -1); // <0 是阻塞监控

    char buf[1024] = {0};
    read(0, buf, sizeof(buf) - 1);
    printf("buf is : %s\n", buf);

    return 0;
}

在这里插入图片描述
在这里插入图片描述

poll非阻塞监控代码

#include <stdio.h>
#include <unistd.h>
#include <poll.h>

//非阻塞监控 0 号文件描述符

int main()
{
    struct pollfd pf;
    pf.fd = 0;
    pf.events = POLLIN;

    while(1)
    {
        int ret = poll(&pf, 1, 0); //0表示非阻塞
        if(ret < 0)
        {
            perror("poll");
            return 0;
        }
        else if(ret == 0)
        {
            printf("poll timeout\n");
            sleep(1);
            continue; //超时,继续监控
        }

        char buf[1024] = {0};
        read(0, buf, sizeof(buf) - 1);
        printf("buf is : %s\n", buf);
    }
    return 0;
}

在这里插入图片描述

poll超时时间监控代码

#include <stdio.h>
#include <unistd.h>
#include <poll.h>

//超时时间监控0号文件描述符

int main()
{
    struct pollfd pf;
    pf.fd = 0;
    pf.events = POLLIN;

    while(1)
    {
        int ret = poll(&pf, 1, 1); 
        if(ret < 0)
        {
            perror("poll");
            return 0;
        }
        else if(ret == 0)
        {
            printf("poll timeout\n");
            sleep(1);
            continue;
        }

        char buf[1024] = {0};
        read(0, buf, sizeof(buf) - 1);
        printf("buf is :%s\n", buf);
    }
    return 0;
}

标签:14,IO,描述符,pf,事件,监控,Linux,poll,buf
来源: https://blog.csdn.net/WL0616/article/details/122765970

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有