【探索Linux】P.48(高级IO —— I/O多路转接之 poll )

news2024/9/21 5:31:25

在这里插入图片描述

阅读导航

  • 引言
  • 一、poll简介
  • 二、poll函数接口
    • ⭕参数说明
  • 三、pollfd结构体
    • ⭕events和revents的取值
  • 四、返回值
  • 五、工作原理
  • 六、优缺点
    • ✅优点
    • ✅缺点
  • 七、 使用示例
    • 🚨注意事项
  • 总结
  • 温馨提示

引言

在上一篇探讨了I/O多路转接之select方法的基础上,本文将深入解析另一种强大的I/O多路转接技术——poll。I/O多路转接作为高效处理多个输入输出流的关键技术,广泛应用于网络编程和文件操作中,旨在提升程序处理并发I/O事件的能力。通过poll,我们可以进一步优化I/O性能,实现更加灵活和高效的资源调度。那么,poll究竟如何工作?它相比select又有哪些优势与差异?让我们一同揭开poll的神秘面纱。

一、poll简介

poll函数是Linux系统下提供的一种I/O多路复用机制,它允许程序同时监视多个文件描述符(如socket描述符)的状态变化,以便在单个线程中高效地处理多个并发连接。

二、poll函数接口

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

⭕参数说明

  • fds:一个指向struct pollfd结构数组的指针,每个元素代表一个需要监视的文件描述符及其事件。
  • nfdsfds数组中元素的数量,即需要监视的文件描述符的数量。
  • timeout:指定poll函数等待事件发生前的超时时间(毫秒)。如果timeout为-1,poll将无限期等待;如果为0,poll将立即返回,不阻塞;如果为正数,poll将等待指定毫秒数。

三、pollfd结构体

pollfd结构体用于指定需要监视的文件描述符及其事件,其定义如下:

struct pollfd {
    int fd;          /* 文件描述符 */
    short events;    /* 等待的事件,通过位或运算组合多个事件 */
    short revents;   /* 实际发生的事件,由内核设置 */
};
  • fd:需要监视的文件描述符。
  • events:用户感兴趣的事件集合,通过位或运算组合多个事件,如POLLIN(可读)、POLLOUT(可写)等。
  • revents:内核在调用返回时设置的实际发生的事件集合。

⭕events和revents的取值

poll函数中,eventsrevents字段都是位掩码(bitmask),它们用于指定和返回文件描述符上发生的事件。下表是一些常见的eventsrevents的取值:

事件描述是否可作为输入是否可作为输出
POLLIN数据(包括普通数据和优先数据)可读
POLLRDNORM普通数据可读
POLLRDBAND优先级带数据可读(Linux不支持)
POLLPRI高优先级数据可读,比如TCP带外数据
POLLOUT数据(包括普通数据和优先数据)可写
POLLWRNORM普通数据可写
POLLWRBAND优先级带数据可写
POLLRDHUPTCP连接被对方关闭,或者对方关闭了写操作。它由GNU引入
POLLERR错误
POLLHUP挂起。比如管道的写端被关闭后,读端描述符上将收到POLLHUP事件
POLLNVAL文件描述符没有打开

🚨🚨注意revents字段可能在poll函数返回时被设置为多个事件的组合,这表示同时发生了多个事件。例如,如果revents被设置为POLLIN | POLLERR,那么表示同时发生了可读事件和错误事件。

四、返回值

  • 成功:返回fds数组中revents域不为0的文件描述符个数,即准备好读、写或出错状态的文件描述符数量。
  • 超时:如果在指定的timeout时间内没有事件发生,返回0。
  • 失败:返回-1,并设置全局变量errno以指示错误原因,如EBADF(无效的文件描述符)、EFAULTfds指针指向的地址超出进程地址空间)、EINTR(调用被信号中断)等。

五、工作原理

poll函数通过轮询的方式检测fds数组中指定的文件描述符的状态。在调用poll函数后,程序会阻塞等待,直到以下情况之一发生:

  1. 指定的文件描述符上有事件发生(如可读、可写)。
  2. 等待时间超时(如果指定了超时时间)。
  3. 调用被信号中断。

当poll函数返回时,程序可以通过检查fds数组中每个元素的revents域来确定哪些文件描述符上发生了事件,并据此进行相应的处理。

六、优缺点

✅优点

  1. 无文件描述符数量限制:与select相比,poll没有最大文件描述符数量的限制(但实际上,当文件描述符数量非常大时,性能会下降)。
  2. 灵活性:允许用户指定多个感兴趣的事件,并可以根据实际发生的事件进行灵活处理。
  3. 超时控制:提供了超时控制机制,允许程序在等待事件发生的同时进行其他操作。

✅缺点

  1. 数据拷贝开销:与select类似,每次调用poll都需要将文件描述符集合从用户空间拷贝到内核空间,无论这些文件描述符是否就绪,这都会带来一定的开销。
  2. 轮询效率:当文件描述符数量非常多时,poll函数的轮询效率会显著下降。

七、 使用示例

以下是一个简单的使用poll函数来监视标准输入(文件描述符0)和普通文件读取事件的示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <poll.h>

#define MAX_EVENTS 10

int main() {
    struct pollfd fds[2];
    char buf[1024];
    int numfds, i;

    // 监视标准输入
    fds[0].fd = 0; // 文件描述符0代表标准输入
    fds[0].events = POLLIN; // 等待读取事件

    // 打开一个文件并监视其读取事件
    int fd = open("example.txt", O_RDONLY);
    if (fd == -1) {
        perror("open");
        exit(EXIT_FAILURE);
    }
    fds[1].fd = fd;
    fds[1].events = POLLIN; // 等待读取事件

    numfds = 2; // 要监视的文件描述符数量

    // 使用poll函数监视文件描述符
    while (1) {
        int ret = poll(fds, numfds, -1); // 无限期等待
        if (ret == -1) {
            // poll函数调用失败
            perror("poll");
            break;
        }

        // 检查哪个文件描述符上的事件发生了
        for (i = 0; i < numfds; ++i) {
            if (fds[i].revents & POLLIN) {
                if (fds[i].fd == 0) {
                    // 标准输入有数据可读
                    if (fgets(buf, sizeof(buf), stdin) == NULL) {
                        // 处理输入结束的情况
                        break;
                    }
                    printf("Read from stdin: %s", buf);
                } else if (fds[i].fd == fd) {
                    // 文件有数据可读
                    ssize_t nread = read(fd, buf, sizeof(buf) - 1);
                    if (nread == -1) {
                        // 处理读取错误
                        perror("read");
                        break;
                    }
                    buf[nread] = '\0'; // 确保字符串以null结尾
                    printf("Read from file: %s", buf);
                }
            }

            // 可以在这里处理其他类型的事件,如POLLOUT、POLLERR等
        }
    }

    close(fd); // 关闭打开的文件
    return 0;
}

🚨注意事项

  • 在使用poll函数时,需要确保fds数组中的所有文件描述符在调用poll函数之前都是有效的。
  • poll函数返回后,fds数组中的revents字段将被内核设置,以反映实际发生的事件。程序需要检查这些字段来确定哪个文件描述符上的事件发生了。
  • 当poll函数返回时,它不会清空fds数组,因此可以连续多次调用poll函数,而无需重新初始化fds数组(除非需要监视不同的文件描述符或事件)。

总结

poll函数是Linux系统下提供的一种强大的I/O多路复用机制,它允许程序同时监视多个文件描述符的状态变化,并通过轮询的方式检测事件的发生。尽管poll函数在灵活性和超时控制方面具有一定优势,但在处理大规模连接时可能会遇到性能瓶颈。因此,在实际应用中需要根据具体场景和需求选择合适的I/O多路复用机制。为了进一步优化大规模连接下的性能表现,Linux还提供了epoll这一更为高效的I/O多路复用机制,我们将在下一篇文章中深入探讨epoll的工作原理及其优势

温馨提示

感谢您对博主文章的关注与支持!如果您喜欢这篇文章,可以点赞、评论和分享给您的同学,这将对我提供巨大的鼓励和支持。另外,我计划在未来的更新中持续探讨与本文相关的内容。我会为您带来更多关于Linux以及C++编程技术问题的深入解析、应用案例和趣味玩法等。如果感兴趣的话可以关注博主的更新,不要错过任何精彩内容!

再次感谢您的支持和关注。我们期待与您建立更紧密的互动,共同探索Linux、C++、算法和编程的奥秘。祝您生活愉快,排便顺畅!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2043777.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第131天:内网安全-横向移动Kerberos 攻击SPN扫描WinRMWinRSRDP

案例一&#xff1a;域横向移动-RDP-明文&NTLM RDP利用的三种方式 1.直接在当前被控主机上进行远程连接 2.建立节点进行连接 3.端口转发&#xff0c;&#xff08;访问当前主机的2222端口等于访问目标的3389&#xff09; 第一种方式(动静太大) 直接利用被控主机进行远程连接…

uniapp left right 的左右模态框

标题 这是组件 <template><div class"content-wrapper"><divv-for"(vla, i) in products":key"i":class"[content-page, getPageClass(i)]"><slot :data"vla"><!-- 用户自定义的内容 --><…

VUE2学习日记 路由

安装路由 路由安装命令&#xff1a; npm install --save vue-router3 创建router文件夹 在src下创建router文件夹 创建index.js 文件 在router文件夹下创建index.js 文件夹 .vue文件的创建 在components文件夹下创建.vue文件 实现 在router文件夹下的index.js中 导入Vu…

搭建内网开发环境(二)|Nexus安装及使用

引言 上一篇教程中按照了 docker 作为容器化工具&#xff0c;在本篇教程中将使用 docker-compose 安装 nexus。 搭建内网开发环境&#xff08;一&#xff09;&#xff5c;基于docker快速部署开发环境 什么是 Nexus Nexus是一个强大的仓库管理器&#xff0c;主要用于搭建和管…

ceph如何增删改查的管理文件

1.创建 Ceph 存储库文件 sudo tee /etc/yum.repos.d/ceph.repo <<EOF [ceph] nameCeph packages for $basearch baseurlhttps://download.ceph.com/rpm-pacific/el8/\$basearch/ enabled1 gpgcheck1 typerpm-md gpgkeyhttps://download.ceph.com/keys/release.asc[ceph-…

200T 数据库非归档无备份恢复---惜分飞

一套近200T的,6个节点的RAC,由于存储管线链路不稳定,导致服务器经常性掉盘,引起asm 磁盘组频繁dismount/mount,数据库集群节点不停的重启,修复好链路问题之后,数据库启动报ORA-01113,ORA-01110 通过Oracle数据库异常恢复检查脚本(Oracle Database Recovery Check)脚本检测,发…

TiDB-从0到1-DM工具

TiDB从0到1系列 TiDB-从0到1-体系结构TiDB-从0到1-分布式存储TiDB-从0到1-分布式事务TiDB-从0到1-MVCCTiDB-从0到1-部署篇TiDB-从0到1-配置篇TiDB-从0到1-集群扩缩容TiDB-从0到1-数据导出导入TiDB-从0到1-BR工具 一、DM原理 支持全量抽取数据\检测新的数据变化同步到下游实例…

易基因:RNA修饰N4-乙酰胞苷(ac4C)的调控机制、检测方法及其在癌症中的作用最新研究进展|新方向

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 N4-乙酰胞苷&#xff08;ac4C&#xff09;是一种高度保守的化学修饰&#xff0c;广泛存在于真核和原核生物RNA中&#xff0c;如tRNA、rRNA和mRNA。这种修饰与多种人类疾病显著相关&#…

【计算机科学的数学基础】二分法查找

二分法查找 问题引入在有序数列中查找 问题引入 问&#xff1a;有15个犯罪嫌疑人排成一排&#xff0c;其中只有1个是真正的“犯人”。你要通过问他们“犯人在哪里&#xff1f;”来找出真正的犯人。没问一次问题都会得到以下3种答案&#xff1a; 我是犯人犯人在我左边犯人在我右…

MATLAB多项式拟合

订阅专栏或下载资源可以获得源代码:https://download.csdn.net/download/callmeup/89632160 拟合和插值 拟合和插值是两种常见的数学方法,用于以某种方式近似或估计实际数据。 拟合是在给定一组已知数据点的情况下,通过选择一个合适的数学模型来拟合数据。拟合的目标是找到…

Mininet应用实践

Mininet应用实践 一、实验目的 &#xff08;1&#xff09;能够运用mininet可视化工具创建网络拓扑结构。 &#xff08;2&#xff09;能够运用mininet交互界面创建网络拓扑结构。 &#xff08;3&#xff09;能够运用python脚本构建网络拓扑结构。 二、实验原理或预习内容 &a…

EmguCV学习笔记 VB.Net 2.2 Matrix类

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 EmguCV学习笔记目录 Vb.net EmguCV学习笔记目录 C# 笔者的博客网址&#xff1a;VB.Net-CSDN博客 教程相关说明以及如何获得pdf教程…

*(论文解读)Prompt-Based Distribution Alignment for Unsupervised Domain Adaptation

Prompt-Based Distribution Alignment for Unsupervised Domain Adaptation 用于UDA的基于提示的分布对齐&#xff08;二区论文&#xff09; 摘要 近年来&#xff0c;尽管大型视觉语言模型&#xff08;VLM&#xff09;在大规模的下游任务中取得了前所未有的成功&#xff0c;…

HTML标签简明通俗教程

HTML标签简明通俗教程 基本知识 HTML&#xff1a;是超文本标记语言&#xff08;Hyper Text Markup Language&#xff09;的缩写&#xff0c;它是用于创建网页的标准标记语言。标签是构成HTML文档的基本单位。 【HTML中的标签&#xff08;tag&#xff09;和元素&#xff08;e…

一款手机壳凭什么卖800元?Casetify品牌策略全解析 | 品牌出海

Casetify官网 巴黎奥运会&#xff0c;张怡宁的手机壳火了。 张怡宁在现场观战并使用手机的照片在网上流传&#xff0c;不是因为这位奥运前冠军&#xff0c;而是她的手机壳。这款满是「花花绿绿」图案的手机壳&#xff0c;迅速被网友发掘出是Casetify品牌的名为「炫彩花卉」的…

Windosw下Visual Studio2022编译OpenCV

OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉和机器学习软件库。它提供了一系列用于处理图像和视频的算法和函数&#xff0c;包括图像处理、特征检测、物体识别、人脸识别等。OpenCV支持多种编程语言&#xff0c;如C、Python、Ja…

从源码到应用:医疗陪诊系统与在线问诊小程序开发详解

在数字化医疗时代&#xff0c;医疗陪诊系统与在线问诊小程序的开发成为了医疗机构和技术公司关注的焦点。接下来&#xff0c;小编将与您一同深入了解。 一、医疗陪诊系统的核心功能 医疗陪诊系统旨在为患者提供更贴心的医疗服务&#xff0c;通过专业人员陪同患者完成就医过程。…

谷歌如何增加网站被收录的机会?

要增加网站被搜索引擎收录的机会&#xff0c;你需要采取一些有效的措施&#xff0c;要确保网站的内容质量高&#xff0c;内容质量不高的内容&#xff0c;哪怕被收录了&#xff0c;之后也是有很大概率会掉的&#xff0c;必须确保内容对用户是有价值的&#xff0c;并且是原创的&a…

ppt文件批量设置打开权限密码的方法

为PPT文件批量设置打开权限密码&#xff0c;可以通过Office软件内置的功能或借助第三方软件来实现。对于少量文件可以用PPT内置的密码设置功能实现&#xff0c;但是对于文件比较多的情况下必须要用到第三方的软件来进行批量设置&#xff0c;以下是一些方法。 一、使用Office软件…

立式报工台助力MES系统打造智能硬件解决方案

信息化与自动化的深度结合&#xff0c;使得企业在生产效率、质量控制以及资源管理等方面得以大幅提升。制造执行系统MES作为连接企业管理层与生产现场的重要桥梁&#xff0c;正在愈发得到重视。为了进一步强化MES系统的功能与应用&#xff0c;立式报工台作为一种新兴的智能硬件…