io多路复用中的poll函数详解

【Linux】多路转接 -- poll函数 poll函数原型如下: 阅读详情

poll函数

poll的机制与select类似,与select在本质上没有多大差别,管理多个描述符也是进行轮询,根据描述符的状态进行处理,但是poll没有最大文件描述符数

主旨思想:

  1. 首先要构造一个关于pollfd数组,将文件描述符和要检测的时间加入数组中
  2. 调用一个poll函数,监听pollfd数组中的文件描述符,直到这些描述符中的一个或者多个进行I/O操作时,该函数才返回。
    a.这个函数是阻塞
    b.函数对pollfd数组的文件描述符的检测的操作是由内核完成的
  3. 在返回时,它会告诉进程有多少个描述符要进行I/O操作。
    #include <poll.h>//头文件
    struct pollfd {
        int fd;  委托内核检测的文件描述符 
        short events;  委托内核检测文件描述符的什么事件 
        short revents;  文件描述符实际发生的事件 
    };
    //实例
    struct pollfd myfd;
    myfd.fd = 5;
    myfd.events = POLLIN | POLLOUT;

    int poll(struct pollfd *fds, nfds_t nfds, int timeout);
    - 参数:
    - fds : 是一个struct pollfd 结构体数组,这是一个需要检测的文件描述符的集合
    - nfds : 这个是第一个参数数组中最后一个有效元素的下标 + 1
    - timeout : 阻塞时长
        0 : 不阻塞
        -1 : 阻塞,当检测到需要检测的文件描述符有变化,解除阻塞
        >0 : 阻塞的时长
    - 返回值:
        -1 : 失败
        >0(n) : 成功,n表示检测到集合中有n个文件描述符发生变化

使用poll函数监听多个文件描述符的服务端程序

#include<stdio.h>
#include<stdlib.h>
#include<arpa/inet.h>
#include<string.h>
#include<unistd.h>
#include<sys/poll.h>
int main(char* argc,int argv){
    //创建socket
    int lfd=socket(PF_INET,SOCK_STREAM,0);

    //绑定
    struct sockaddr_in saddr;
    saddr.sin_port=htons(9999);
    saddr.sin_family=AF_INET;
    inet_pton(AF_INET,"127.0.0.1",&saddr.sin_addr.s_addr);
    bind(lfd,(struct sockaddr*)&saddr,sizeof(saddr));

    //监听
    listen(lfd,8);//连接与未连接最多8个

    //创建pollfd数组
    struct pollfd fds[128];
    for(int i=0;i<128;++i){
        fds[i].fd=-1;
        fds[i].events=POLLIN;//检测是否有数据可读
    }
    fds[0].fd=lfd;
    int nfds=0;//数组的最大下标

    while(1){
        //调用poll系统函数,让内核帮忙检测文件描述符是否有数据可读
        int ret=poll(fds,nfds+1,-1);//阻塞
        if(ret==-1){
            perror("poll");
            exit(0);
        }else if(ret==0){
            //超时时间到了   没有检测到  就为0  
            //程序中设置为永久阻塞  所以不会出现这种情况
            continue;
        }else{
            // 说明检测到了有文件描述符的对应的缓冲区的数据发生了改变
            if(fds[0].revents&POLLIN) {
                // 表示有新的客户端连接进来了
                struct sockaddr_in cliaddr;
                int len = sizeof(cliaddr);
                int cfd = accept(lfd, (struct sockaddr *)&cliaddr, &len);

                //获取客户端信息
                char clientIp[16];
                inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr,clientIp,sizeof(clientIp));
                unsigned int clientPort=ntohs(cliaddr.sin_port);
                printf("客户端ip:%s,端口:%d\n",clientIp,clientPort);

                // 将新的文件描述符加入到集合中
                for(int i=1;i<128;++i){
                    if(fds[i].fd==-1){
                        fds[i].fd=cfd;
                        fds[i].events=POLLIN;
                        nfds=nfds>i?nfds:i;//更新最大的pollfd数组下标
                        break;
                    }
                }
                
            }
            //监听的文件描述符肯定在最前面
            for(int i=1;i<=nfds;++i){
                if(fds[i].revents&POLLIN){
                    //说明客户端发来的数据
                    char recvBuf[100]={0};
                    int len=read(fds[i].fd,recvBuf,sizeof(recvBuf));
                    if(len>0){
                        printf("read buf = %s\n", recvBuf);
                        write(fds[i].fd, recvBuf, strlen(recvBuf) + 1);
                    }else if(len==0){
                        printf("client close...\n");
                        close(fds[i].fd);
                        fds[i].fd=-1;
                    }else{
                        perror("read");
                        exit(-1);
                    }
                }
            }
        }
    }
    close(lfd);
    return 0;
}

poll函数的缺点:

1.每次调用poll,都需要把pollfd数组从用户态拷贝到内核态,这个开销在过很多时会很大
2.同时每次调用select都需要在内核遍历传递进来的所有pollfd,这个开销在很多时
也很大
3.只会返回有几个文件描述符可以读写 具体是哪几个 还需要在用户程序中遍历

poll与select的区别:

1.poll与select不同,通过一个pollfd数组向内核传递需要关注的事件,故没有描述符个数的限制
2.pollfd中的events字段和revents分别用于标示关注的事件和发生的事件,故pollfd数组只需要被初始化一次。

IO多路复用之poll函数详解 poll  poll的机制与select类似,与select在本质上没有多大差别,管理多个描述符也是进行轮询,根据描述符的状态进行处理,但是poll没有最大文件描述符数量的限制。   poll和select同样存在一个缺点就是,包含大量文件描述符的数组被整体复制于用户态和内核的地址空间之间,而不论这些文件描述符是否就绪,它的开销随着文件描述符数量的增加而线性增大。poll函数  函数格式如下所示: 阅读详情

相关推荐

IO多路复用大揭秘------彻底搞懂poll函数

欢迎交流 QQ 2431173627 微信 ccc17862701790 设计思路 对于poll函数工作过程的理解 poll函数工作原理与select函数类似,也是监管一系列的文件描述符, 看这些文件描述符是否可读/可写/异常,再去调用io函数读写 不过poll函数没有监管文件描述符个数的限制, 与 select() 在本质上没有多大差别,管理多个描述符也是进行轮询,根据描...

vjhghjghj的博客 1718

poll函数详解

1 poll函数概述 select() 和 poll() 系统调用的本质一样,poll() 的机制与 select() 类似,与 select() 在本质上没有多大差别,管理多个描述符也是进行轮询,根据描述符的状态进行处理,但是 poll() 没有最大文件描述符数量的限制(但是数量过大后性能也是会下降)。poll() 和 select() 同样存在一个缺点就是,包含大量文件描述符的数组被整体...

skypeng57的专栏 4万+

Linux网络编程(多路IO复用poll)

上篇文章我们讲解了使用select进行IO复用,这篇文章我们来讲解使用poll函数来进行多路IO复用。本篇文章主要讲解到了poll函数的使用方法并且使用poll实现了一个并发服务器,这个大家可以结合上篇文章的select函数进行对比思考。

m0_49476241的博客 499

poll函数详解及原理

poll函数实现和select极为相似,但是它们的接口并不相同:int poll(struct pollfd fdarray[], nfds_t nfds, int timeout); int select(int maxfdp1, fd_set restrict readfds, fd_set *restrict expectfds, struct timeval restrict tvptr

fengasdfgh的博客 1万+

ESP32驱动Xbox Series X手柄的BLE协议实现

蓝牙低功耗(BLE)是嵌入式设备无线交互的核心技术,其GATT协议架构支持自定义服务与特征值通信,广泛应用于游戏外设、工业遥控等场景。Xbox Series X手柄采用非标准私有BLE协议,需深度解析输入报告(64字节)、输出控制(振动/LED)及固件兼容性约束。该方案依托ESP32平台与NimBLE 2.1.0+协议栈,解决MTU协商、PHY配置与HCI事件同步等关键问题,实现125Hz实时输入采集与毫秒级振动反馈。适用于机器人遥操作、ROS2终端、LVGL交互界面等工程实践,是私有BLE设备逆向集成的典

weixin_42610671的博客 710

HDMI2.1 FRL流控 概览

HDMI 2.1 FRL的流控本质是。

叫好与叫座虽然不是对立面,但想在同一个作品中达到双重效果很难。 2083

select( )、poll( )、epoll( )函数详解

1、slect()函数 1.1、函数原型 #include <sys/time.h> int select(int maxfdp, fd_set* readfds, fd_set* writefds, fd_set* errorfds, struct timeval* timeout); (1)maxfdp:指集合中所有文件描述符的范围,即所有文件描述符的最大值加1,不能错; (2)readfds:要监视读操作的文件描述符集合; (3)writefds:要监视写操作的文件描述符集合;

weixin_42031299的博客 1744

Spring AI 实战:5 分钟搭建你的第一个 AI 应用(含完整代码)

能力关键 API适用场景基础对话简单问答、文本生成流式输出实时打字机效果@Bean模型需要调用外部工具结构化输出需要返回 Java 对象多轮对话聊天机器人场景Spring AI 让 Java 开发者可以用最熟悉的方式(Spring Boot + Maven)进入 AI 应用开发领域,不用学新语言,不用换框架,这是它最大的优势。但目前为止,我们的 AI 应用只能回答"它脑子里已有的知识"。如果让它读懂你自己的技术文档、公司内部知识库呢?这就是下一篇文章的主题——RAG(检索增强生成)实战。

qq_17204557的博客 643

【Linux:IO多路复用(select、poll函数)

nfds:是在这三个文件描述符集合中找出一个最大的文件描述符再+1内核中需要线性遍历这些集合中的文件描述符,该值是循环结束的条件该参数在windows中无效,指定为-1即可readfds:读集合一般都是需要进行检测的,这样才能知道哪些文件描述符可以接收数据writefds:内核只检测这个集合中的文件描述符对应的写缓冲区,如果不使用该参数可以用NULL指定exceptfds:内核只检测这个集合中的文件描述符是否有异常状态,如果不使用该参数可以用NULL指定。

2201_75755162的博客 2190

一种4位sar adc仿真验证

4位sar adc采用下图的电容阵列,电路如下图:所有电容的正端(也称为上极板)与比较器的反相端连接,比较器同相端接Vin,其工作过程进行大致分析见之前的文章《一种4位sar adc工作过程推导(三)》,下面对这个电路进行仿真验证。 两个参考电压VrefPV_{refP}VrefP​和VrefNV_{refN}VrefN​,V+=VinV_{+}=V_{in}V+​=Vin​,假设1116(VrefP−VrefN)+VrefN<Vin<1216(VrefP−VrefN)+VrefN\frac{

大学生视野 1954

开关变换器分析:大信号模型与小信号模型

是电力电子系统建模中的两类基本方法,分别用于描述系统在不同工作条件下的动态行为。它们的核心区别在于是否对变量进行线性化近似,以及适用的分析场景。

创新改变世界! 1907

IO多路复用之poll函数-非阻塞版本

本文介绍了IO多路复用中poll函数的非阻塞版本实现。首先对比了poll阻塞/非阻塞模式的特点,以及socket阻塞/非阻塞模式的区别,重点分析了timeout参数对poll行为的影响。通过表格形式详细展示了不同组合的应用场景和特性:poll阻塞+非阻塞socket是最高效的常见组合。文中提供了设置socket非阻塞的代码示例,并给出了一个完整的poll阻塞+非阻塞socket的服务器实现,采用水平触发模式处理数据接收。该实现通过单线程高效处理多连接,避免了线程阻塞问题,适合高并发网络服务场景。

多多爱学习 1252

逆变器LCL滤波器参数设计(一)

1.基本介绍 并网型逆变器一般是电流源逆变器,滤波器基本用LCL结构。 假设要设计额定功率10KVA的单相逆变器,采用两电平的全桥拓扑,采用SPWM控制,载波频率20KHz,电网等级220V,频率50Hz。 拓扑结构如图所示: 直流输入电压分为上下母线各1/2Vin,半母线电压为380V。 L1采用高频磁芯绕制,称为高频电感;L2用工频电感绕制,称工频电感;C是滤波电容,为高频谐波电流提供通路;Vg为电网电压。 载波调制比为:Mr=220*1.414/380=0.819 2.高频电感量的计算 逆变器可以等

weixin_43549807的博客 5万+

UNIX实现IO多路复用之使用poll函数实现网络socket服务端

一,前言 UNIX下存在五种网络模型,分别是:同步阻塞IO,同步非阻塞IO,信号驱动IO,异步IO和今天要介绍的IO多路复用。 那么IO多路复用解决的问题是什么呢? 我们知道在UNIX下的很多函数都是阻塞的,阻塞是指IO操作在没有接收完数据或者没有得到结果之前不 会返回,需要彻底完成后才返回到用户空间;假设我们现在面临这样一个问题:我们需要在一个程序里要查看按键是否要按下,同时他还要从串口里读取数据进行处理,也要处理网络上来的数据,如果只是普通的利用三个read调用来解决,如果按键这时没按下(即数据没

qq_59580408的博客 467

python基础之语言发展历史

博主简介:原互联网大厂tencent员工,网安巨头Venustech员工,阿里云开发社区专家博主,微信公众号java基础笔记优质创作者,csdn优质创作博主,创业者,知识共享者,欢迎关注,点赞,收藏。 目录一、前言二、发展历史1、Python是一种面向对象的解释型编程语言2、Python常被称为胶水语言3、Python由Guido开发4、Python连续多年入选编程语言TOP105、Python的发展历史三、总结 一、前言   由于Python语言的简洁性、易读性以及可扩展性,它在网络爬虫、数据分析、.

jiankang66的博客 3348

Open3D 进阶(22)间接平差法拟合空间曲线

空间曲线拟合在电力线三维重建中有着广泛的应用,本文利用python使用间接平差法对三维空间曲线的拟合进行代码实现。

点云侠的博客 1057

C语言 IO多路复用——poll函数

友链 gcc 1.c -o 1 -lpthread ctrl+f搜索服务端代码和客户端代码获取代码 该方法也可以实现并发服务器 IO多路复用,IO多路转接 简介 IO多路复用中的IO并不是指单纯的标准输入和输出 这里的IO指的是程序和内存之间的IO 从程序将数据写入内存就叫做输出 从内存中将数据读入程序中就叫做输入 socket通信过程中也牵涉到大量的IO操作 在unix中,socket不过就是一个文件描述符,对应内核中的一块缓冲区 缓冲区分为读缓冲区和写缓冲区 IO多路复用具体指的就是对读写缓冲区的操作

ma_de_hao_mei_le的博客 3438

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

IO多路复用,使用select,poll,epoll三个函数分别实现

有关IO多路复用的select,poll,epoll三个函数的基本操作

m0_68210771的博客 397

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

【linux系统】IO多路复用的三个函数select、poll和epoll

IO多路复用的三个函数select、poll和epoll1.引出IO多路复用2.select函数——同步IO多路复用3.poll函数——等待一个fd上的events4.epoll函数——IO事件通知5.三个函数的比较 1.引出IO多路复用 以下内容参考了https://blog.youkuaiyun.com/SkydivingWang/article/details/74917897 我们都知道unix(...

moX980的博客 770

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

IO多路复用概念以及所需要用到的函数select、poll、epoll

IO多路复用概念以及所需要用到的函数select、poll、epoll

y_bra_ke的博客 262

poll函数_IO多路复用之poll函数

select 机制缺点:1.每次调用 select(),都需要把 fd 集合从用户态拷贝到内核态,这个开销在 fd 很多时会很大,同时每次调用 select() 都需要在内核遍历传递进来的所有 fd,这个开销在 fd 很多时也很大。2.单个进程能够监视的文件描述符的数量存在最大限制,在 Linux 上一般为 1024,可以通过修改宏定义甚至重新编译内核的方式提升这一限制,但是这样也会造成效率的降低...

weixin_39824033的博客 210

IO多路复用之poll函数详解用法-带详细注释-阻塞版本

IO多路复用poll函数详解 poll是一种IO多路复用机制,允许单线程同时监听多个文件描述符的事件状态。介绍了poll的使用,以及常用事件标志宏;与select的对比;以及poll的工作流程和示例

多多爱学习 617

IO多路复用——poll函数

Linux IO多路复用——poll函数

PANTAN_优快云的博客 975
上一篇: io多路复用中的select函数详解
下一篇: io多路复用中的epoll函数详解
nuaa蟑螂恶霸
博客等级 码龄8年 21粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值