Linux高级IO——多路转接之poll

本章代码Gitee地址:PollServer

文章目录

    • 1. poll
    • 2. poll_server

1. poll

poll的作用和select一模一样,只负责等待

pollselect的基础之上解决了select的两个硬伤:

  1. select等待的fd有上限
  2. select输入输出参数较多
#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
  • struct pollfd *fds

    struct pollfd {int   fd;	//关心的文件描述符     short events;	//关心的事件 用户->内核	(位图)short revents;	//返回关心的事件	内核->用户	(位图)
    };
    
    事件(位图值)描述
    POLLIN数据可读
    POLLOUT数据可写
    POLLERR发生错误
    POLLHUP挂起
    POLLNVAL文件描述符无效
    POLLPRI高优先级数据(例如:TCP紧急指针)
  • nfds_t nfds:等待多个文件描述符当中值最大的+1,即maxfd+1

  • int timeout:等待时间,单位是毫秒;如果设为-1,表述阻塞等待

  • 返回值:
    > 0:有n个fd已经就绪
    == 0:等待超时,没有错误,没有文件描述符就绪
    < 0:等待出错

2. poll_server

#pragma once
#include<iostream>
#include<string>
#include<sys/time.h>
#include<poll.h>
#include"Socket.hpp"
#include"Log.hpp"static const uint16_t defaultport = 8089;
static const int fd_max = 64;
const int defaultfd = -1;
const int non_events = 0;class PollServer
{
public:PollServer(uint16_t port = defaultport):_port(port){for(int i = 0; i < fd_max; i++){_events_fd[i].fd = defaultfd;_events_fd[i].events = non_events;_events_fd[i].revents = non_events;}}bool Init(){_listensock.Socket();_listensock.Bind(_port);_listensock.Listen();return true;}void Accepter(){std::string clientip;uint16_t clientport;int sock = _listensock.Accept(&clientip, &clientport); // 此时并不会阻塞, 因为已经上层通知事件已经就绪if (sock < 0)return;log(Info, "accept success, %s:%d, sockfd:%d", clientip.c_str(), clientport, sock);int pos = 1;for (; pos < fd_max; pos++){if (_events_fd[pos].fd != defaultfd)continue;elsebreak;}if (pos == fd_max) // 文件描述符满了(位图满了){log(Warning, "server is full, close %d", sock);//可以扩容close(sock);}else{_events_fd[pos].fd = sock;_events_fd[pos].events = POLLIN;_events_fd[pos].revents = non_events;PrintFd();              // Debug}}void Recver(int fd, int pos){// 读事件就绪char buffer[1024];ssize_t n = read(fd, buffer, sizeof(buffer) - 1);if (n > 0){buffer[n] = 0;std::cout << "get a message: " << buffer << std::endl;}else if (n == 0){log(Info, "client quit, me too, close fd:%d", fd);close(fd);_events_fd[pos].fd = defaultfd; // 从select中移除}else{log(Warning, " read error, close fd:%d", fd);close(fd);_events_fd[pos].fd = defaultfd;}}void Dispatcher(){for (int i = 0; i < fd_max; i++){int fd = _events_fd[i].fd;if(fd == defaultfd) continue;if (_events_fd[i].revents & POLLIN){if(fd == _listensock.Getfd())     //是监听套接字且已经就绪 获取新链接{Accepter();}else{Recver(fd, i);}//其他的事件...}}}void Start(){int listensock = _listensock.Getfd();_events_fd[0].fd = listensock;_events_fd[0].events = POLLIN;int timeOut = 1500; //1.5sfor( ; ; ){//不可直接accept, accept本质是检测并获取listensock上面的事件struct timeval timeout = {2, 0};    //输入输出型参数, 需要周期性重复设置//int s = select(maxfd + 1, &rfds, nullptr, nullptr, &timeout);int p = poll(_events_fd, fd_max, timeOut);switch (p){case 0://等待超时std::cout << "time out..." << std::endl;break;case -1://等待出错std::cerr << "poll error" << std::endl;break;default://有事件就绪std::cout << "get a link" << std::endl; //如果上层一直不处理,底层则一直触发Dispatcher();break;}}}//Debugvoid PrintFd(){std::cout << "online fd list: ";for(int i = 0; i < fd_max; i++){if(_events_fd[i].fd != defaultfd)std::cout << _events_fd[i].fd << " ";}std::cout << std::endl;}~PollServer(){}
private:MySocket _listensock;uint16_t _port;struct pollfd _events_fd[fd_max];// int _rfd_array[fd_max];
};

虽然poll解决了select文件描述符有上限和每次都要对文件描述符进行重置的问题,但是这些都交给了操作系统,虽然poll不设上限,但是操作系统有上限,而且操作系统是要在底层遍历的

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

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

相关文章

【软件设计师知识点】八、数据库技术基础

文章目录 数据库基本术语关系型数据库基本术语数据库模型三级模式二级映射数据的独立性数据模型常用数据模型E-R 图(概念设计)数据库操作完整性规则关系代数运算集合运算符关系运算符数据库语言 SQL数据定义语言(DDL)

uniapp开发小程序手写板、签名、签字

可以使用这个插件进行操作 手写板-签名签字-lime-signature - DCloud 插件市场 但是目前这个插件没有vue3 setup Composition API的写法。所以对于此文档提供的可以直接使用,需要使用Composition API方式实现的,可以继续看。 因为Composition API方式,更加的简单、灵活,…

Java编程题目 | 四个数的三三组合

大家可以关注一下专栏&#xff0c;方便大家需要的时候直接查找&#xff0c;专栏将持续更新~ 题目描述 使用数字1、2、3、4&#xff0c;编写一个Java程序&#xff0c;找出所有互不相同且每个三位数中不含有重复数字的组合&#xff0c;并输出这些组合。 解题思路 使…

记录一个腾讯云上kafka不能正常启动问题

问题描述&#xff1a;刚在新的腾讯云三台节点上安了Zookeeper和kafka&#xff0c;改好对应配置文件后&#xff0c;启动zk和kafka。 启动zk后&#xff0c;启动kafka jpsall以后 发现两个进程都启了&#xff08;这里有猫腻&#xff0c;kafka其实没起来&#xff0c;过几秒就自动掉…

在Windows中用命令行编译C项目

在Windows中可以用命令行编译C项目 官方指导文档&#xff1a; 演练&#xff1a;在命令行上编译 C 程序 | Microsoft Learn 在官方文档中可以看到&#xff0c;可以只安装VS的命令行工具集&#xff0c;如下图所示

2.0 Hadoop 运行环境

2.0 Hadoop 运行环境 分类 Hadoop 教程 由于 Hadoop 是为集群设计的软件&#xff0c;所以我们在学习它的使用时难免会遇到在多台计算机上配置 Hadoop 的情况&#xff0c;这对于学习者来说会制造诸多障碍&#xff0c;主要有两个&#xff1a; 昂贵的计算机集群。多计算机构成的…

JVM性能调优——GC日志分析

文章目录 1、概述2、生成GC日志3、Parallel垃圾收集器日志解析3.1、Minor GC3.2、FULL GC 4、G1垃圾收集器日志解析4.1、Minor GC4.2、并发收集4.3、混合收集4.4、Full GC 5、CMS垃圾收集器日志解析5.1、Minor GC5.2、Major GC5.3、浮动垃圾 6、日志解析工具6.1、GCeasy6.2、GC…

SpringBoot项目 jar包方式打包部署

SpringBoot项目 jar包方式打包部署 传统的Web应用进行打包部署&#xff0c;通常会打成war包形式&#xff0c;然后将War包部署到Tomcat等服务器中。 在Spring Boot项目在开发完成后&#xff0c;确实既支持打包成JAR文件也支持打包成WAR文件。然而&#xff0c;官方通常推荐将Sp…

【Godot4.2】CanvasItem绘图函数全解析 - 8.绘制点索引

概述 在示意图绘制过程中或者测试过程中&#xff0c;可能需要标记点的索引。 最常见的形式就是用一个圆圈作为背景&#xff0c;用阿拉伯数字作为索引。 实现的重点是动态计算背景圆的半径。原理是&#xff0c;获取字符串的矩形&#xff0c;取对角线长度的一半作为外接圆的半…

AI PC元年,华为的一张航海图、一艘渡轮和一张船票

今天&#xff0c;从学术研究者到产业投资者&#xff0c;无不认为大模型掀起了一场人工智能的完美风暴。 所谓“完美风暴”&#xff0c;指的是一项新技术的各个要素&#xff0c;以新的方式互相影响、彼此加强&#xff0c;组合在一起形成了摧枯拉朽般的力量。 而我们每个人&#…

【运维笔记】深入理解反向代理的原理及应用

一、引言 在现代网络架构中&#xff0c;反向代理是一个核心组件&#xff0c;它在提升网站性能、增加安全性和简化网络流量管理方面发挥着至关重要的作用。本文将深入探讨反向代理的原理&#xff0c;展示其在不同场景下的应用&#xff0c;并通过具体案例来说明如何实现和优化反…

【opencv】示例-phase_corr.cpp 捕获视频流并通过计算相位相关性来检测画面中的移动...

// 包含OpenCV库的头文件 #include "opencv2/core.hpp" // 包含OpenCV核心功能 #include "opencv2/videoio.hpp" // 包含视频IO功能 #include "opencv2/highgui.hpp" // 包含高级GUI功能&#xff0c;显示图像 #include "opencv2/imgproc.hp…

机器视觉系列之【硬件知识】-工业相机(三)

目录 几个高频面试题目 如何解决工业相机的丢帧现象 工业相机是怎么实现触发的?

SpringCloud 2021.0.9 OpenFeign 与 circuitbreaker-resilience4j 使用示例

背景 OpenFeign是微服务中服务远程调用组件。 circuitbreaker 是断路器的抽象接口。 resilience4j是断路器的一种实现。 在服务间远程调用过程中&#xff0c;为了避免服务雪崩&#xff0c;需要设置失败保护机制&#xff0c;当下游服务超时或者不可用时&#xff0c;上游服务可…

Eureka-搭建Eureka步骤

简介&#xff1a; Eureka是Netflix开发的服务发现框架&#xff0c;本身是一个基于REST的服务&#xff0c;主要用于定位运行在AWS域中的中间层服务&#xff0c;以达到负载均衡和中间层服务故障转移的目的。SpringCloud将它集成在其子项目spring-cloud-netflix中&#xff0c;以实…

【OTA】STM32新能源汽车OTA技术ymodem协议PC串口升级过程

【OTA】STM32新能源汽车OTA技术ymodem协议PC串口升级过程 文章目录 前言一、实验工具1.串口USB线——烧录APP2生成的BIN文件2.STLINK——烧录BOOT代码和APP1代码3.烧录工具——将BIN文件烧录到单片机中4.FLYMCU——清除芯片FLASH 二、硬件绘制1.原理图2.PCB 三、软件配置1.BOOT…

Github 2024-04-13 开源项目日报 Top9

根据Github Trendings的统计,今日(2024-04-13统计)共有9个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目2C++项目2Jupyter Notebook项目2TypeScript项目1Cuda项目1非开发语言项目1GoogleTest - Google测试和模拟框架 创建周期:3181 天开发…

订单状态及其转换

目录 新建状态&#xff08;Created&#xff09;/待处理&#xff08;Pending&#xff09; 待支付&#xff08;Pending Payment&#xff09; 支付确认中&#xff08;Payment Processing&#xff09; 支付成功&#xff08;Paid&#xff09; 处理中&#xff08;Processing&…

【2024-03-14】Spring中基于注解和AOP的结合实现(改造系统中的原有AOP鉴权)

业务需求 改造系统中的原先写的通过表达式拦截实现的鉴权功能。 原有逻辑 没有注释&#xff08;啊啊啊啊&#xff09;。 花费工时7.5小时。 步骤如下&#xff1a; 获取Header头参数。校验Header头的必要参数。通过Header中获取的参数&#xff0c;查询数据库入口表信息。通过…

【软件设计师知识点】三、数据结构

文章目录 逻辑结构与物理结构线性结构线性表顺序存储链式存储栈和队列栈和队列的基本性质循环队列双端队列栈与队列的应用串非线性结构数组矩阵树与二叉树树的基本术语二叉树的性质特殊二叉树<