当前位置: 首页 > news >正文

服务器(I/O)之多路转接

五种IO模型

1、阻塞等待:在内核将数据准备好之前,系统调用会一直等待。所有的套接字,默认都是阻塞方式。

2、非阻塞等待:如果内核没有将数据准备好,系统调用仍然会返回,并且会返回EWUOLDBLOCK或者EAGAIN错误码。

3、信号驱动:内核将数据准备好的时候,使用SIGIO信号通知应用程序进行IO操作。

4、多路转接(多路转接):能够同时等待多个文件句柄的就绪状态。

5、异步IO:由内核在数据拷贝完成时,通知应用程序。(而信号驱动是告诉应用程序什么时候可以开始拷贝数据)。

前四种都属于同步IO,第五种属于异步IO。同步IO和异步IO,区别在于同步IO会参与IO结果的获取的过程。而异步IO则是不会参与IO结果获取的过程,直接拿到最终的IO结果。

IO的本质就是等和拷贝数据。也就是说没有数据的时候,就需要等待数据,当有数据的时候,再将数据拷贝走。而高效的IO,要达到高效,关键在于减少等的比重才能达到效果。在上述的五种IO模型中,多路转接的方式,一次等待多个文件描述符,在某种意义上等的效率更高,也就是说一次等通知多个就绪能够进行拷贝的文件描述符。

I/O多路转接之select

select系统调用是用来让我们的程序监视多个文件描述符的状态变化的; 程序会停在select这里等待,直到被监视的文件描述符有一个或多个发生了状态改变;

函数原型

参数解释:

nfds表示最大文件描述符+1。

readfdswritefdsexceptfds(位图结构)分别需要检测的可读文件描述符集合、可写文件描述符集合和异常文件描述符集合。

timeout表示设置select()的等待时间。(timeout取值(NULL、0、特定时间)

NULL表示阻塞等待,

0则表示仅检测描述符集合的状态,然后立即返回,

特定时间值表示select的等待时间)。

操作fd_set位图结构的接口

函数返回值

执行成功---->则返回文件描述词状态已改变的个数

如果返回0---->代表在描述词状态改变前已超过timeout时间,没有返回

当有错误发生时则---->返回-1,错误原因存于errno,此时参数readfds,writefds, exceptfds和timeout的 值变成不可预测。

select特点

可监控的文件描述符个数取决与sizeof(fd_set)的值. 我这边服务器上sizeof(fd_set)=512,每bit表示一个文件描述符,则我服务器上支持的最大文件描述符是512*8=4096.

将fd加入select监控集的同时,还要再使用一个数据结构array保存放到select监控集中的fd,         一是用于再select 返回后,array作为源数据和fd_set进行FD_ISSET判断。

        二是select返回后会把以前加入的但并无事件发生的fd清空,则每次开始select前都要重新从array取得fd逐一加入(FD_ZERO最先),扫描array的同时取得fd最大值maxfd,用于select的第一个参数。

select缺点

每次调用select, 都需要手动设置fd集合, 从接口使用角度来说也非常不便.

每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大

每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大

select支持的文件描述符数量太小

I/O多路转接之poll

函数原型

参数解释:

fds是一个poll函数监听的结构列表. 每一个元素中, 包含了三部分内容: 文件描述符, 监听的事件集合, 返回的事件集合.

其中events和revents的取值可以为如下。比如POLLIN或者POLLOUT但是某一位为1的宏,可以设置进events或者内核设置进revents中。

nfds表示fds数组的长度

timeout表示poll函数的超时时间, 单位是毫秒(ms).

返回值

返回值  <  0, 表示出错;

返回值  =  0, 表示poll函数等待超时;

返回值  >  0, 表示poll由于监听的文件描述符就绪而返回

poll的优点

不同与select使用三个位图来表示三个fdset的方式,poll使用一个pollfd的指针实现

        pollfd结构包含了要监视的event和发生的event,不再使用select“参数-值”传递的方式. 接口使用比 select更方便

        poll并没有最大数量限制 (但是数量过大后性能也是会下降,因为需要轮询的检测就绪的事件).

poll的缺点

在监听的文件句柄增多时

和select函数一样,poll返回后,需要轮询pollfd来获取就绪的描述符.

每次调用poll都需要把大量的pollfd结构从用户态拷贝到内核中.

同时连接的大量客户端在一时刻可能只有很少的处于就绪状态, 因此随着监视的描述符数量的增长, 其效率也会线性下降.

I/O多路转接之epoll

函数原型

创建epoll句柄

epoll的函数与select和poll的函数不同,epoll的函数有三个分别独立完成各自功能。

参数size表示所创建的epoll模型,最大能监听文件句柄的数目。

返回值

success -----> return 正数。fail -----> return -1

将要监控的文件描述符进行注册

参数:

        epfd表示我们所创建的epoll模型的文件句柄。

        op表示关心添加的文件句柄的什么行为。用三个宏来表示。

                EPOLL_CTL_ADD :注册新的fd到epfd中;

                EPOLL_CTL_MOD :修改已经注册的fd的监听事件;

                EPOLL_CTL_DEL :从epfd中删除一个fd;

        fd表示我们需要添加关心的文件句柄

        event表示我们关心添加的文件句柄的什么事件。epoll_event结构体如下:

                

                其中events可以是一下宏的集合

返回值:

success -----> return 0。fail -----> return -1

等待文件描述符就绪

参数:

        epfd表示我们所创建的epoll模型的文件句柄。

        events表示系统监听到文件句柄的事件就绪并拷贝至用户的结构体数组

        maxevents表示events数组的大小。

        timeout表示超时时间(毫秒,0会立即返回,-1是永久阻塞)。

返回值:

        success ----> return 就绪的文件描述符的个数。

        超时  ----->  return 0

        fail  ----> return -1

多路转接的工作原理

首先,epoll的使用是一个单进程,因此我们可以通过进程找到对应的epoll句柄。

select和poll的原理:忽略其中的1、2和文件句柄,就单单看3。当外设将数据通过驱动刷新到对应文件句柄中,该文件句柄就就绪了。但是使用者需要轮询遍历3这个队列。

epoll的原理:现在我们需要将上图看作一个整体,epoll模型中存在一个红黑树存放关心的文件句柄,并带有回调函数。当外设将数据通过驱动刷新到对应文件句柄中,该文件句柄就就绪了。然后调用其回调函数,将3中就绪的文件句柄添加到2中的就绪队列中。也就是说,epoll不用再轮询遍历3这个队列了,直接遍历2这个就绪队列就能拿到所有就绪的文件句柄了。

        其次,epoll中维护着红黑树、就绪队列等数据结构,在Linux中都是交由文件管理的。着就是为什么要创建epoll模型,也就是epoll文件句柄了。

        epoll中的三个函数epoll_create、epoll_ctl、epoll_wait,epoll_create函数负责创建句柄,并初始化队列3的大小。epoll_ctl函数负责向红黑树中添加关心的文件句柄,并注册回调函数。epoll_wait函数则是遍历就绪队列2,拿到就绪的文件句柄。

相关文章:

服务器(I/O)之多路转接

五种IO模型 1、阻塞等待&#xff1a;在内核将数据准备好之前&#xff0c;系统调用会一直等待。所有的套接字&#xff0c;默认都是阻塞方式。 2、非阻塞等待&#xff1a;如果内核没有将数据准备好&#xff0c;系统调用仍然会返回&#xff0c;并且会返回EWUOLDBLOCK或者EAGAIN错…...

后端面试话术集锦第 十三 篇:java集合面试话术

这是后端面试集锦第十三篇博文——java集合面试话术❗❗❗ 1. Java里常见的数据结构都有哪些以及特征 数组 数组是最常用的数据结构。 数组的特点是长度固定,可以用下标索引,并且所有的元素的类型都是一致的。 列表 列表和数组很相似,只不过它的大小可以改变。 列表一般都是…...

《微服务架构设计模式》第一章

逃离单体地狱 FTGO单体架构 ​​​​​​​作者用国外FTGO公司&#xff08;一家做线餐饮外卖&#xff09;的应用程序举例&#xff0c;阐述了单体架构的优缺点。FTGO应用架构如下&#xff1a; 应用程序是单体应用&#xff0c;具有六边形架构&#xff0c;最内侧是业务逻辑&…...

前端是如何打包的

前端项目的打包过程通常涉及将多个源文件&#xff08;包括HTML、CSS、JavaScript等&#xff09;合并、优化和压缩&#xff0c;以生成最终用于生产环境的静态资源。这个过程可以使用构建工具和打包工具来自动化完成。以下是前端项目的常见打包步骤&#xff1a; 1. **源代码编写…...

Qt 5.15编译(MinGW)及集成Crypto++ 8.7.0笔记

一、背景 为使用AES加密库&#xff08;AES/CBC加解密&#xff09;&#xff0c;选用Crypto 库&#xff08;官网&#xff09;。   最新Crypto C库依次为&#xff1a;8.8.0版本&#xff08;2023-6-25&#xff09;、8.7.0&#xff08;2022-8-7&#xff09;和8.6.0&#xff08;202…...

Qt 简单闹钟

//wiget.h#ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTime> //时间类 #include <QTimer> //定时器类 #include <QTextToSpeech> #include <QDebug> QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPA…...

简单谈下Spring、Spring MVC和Spring Boot

Spring是一个开源的轻量级框架&#xff0c;用于构建Java应用程序。它提供了一种全面的编程和配置模型&#xff0c;可以帮助开发人员构建各种类型的应用程序&#xff0c;从简单的控制台应用程序到大型企业级应用程序。Spring框架的主要目标是提高应用程序的可维护性、可扩展性和…...

利用python进行视频下载并界面播放快速下载素材

工具&#xff1a;python designer&#xff08;python自带&#xff09;:UI界面设计工具 VLC&#xff1a;视频播放工具 需要的库如下&#xff1a; import os,platform os.environ[PYTHON_VLC_MODULE_PATH] "./vlc-3.0.14" import vlc from 脚本 import Player from …...

[C++][pcl]pcl安装后测试代码3

测试环境&#xff1a; vs2019 pcl1.12.1 代码&#xff1a; #include<iostream> #include <thread>#include <pcl/common/common_headers.h> #include <pcl/features/normal_3d.h> #include <pcl/io/pcd_io.h> #include <pcl/visualizatio…...

在WSL下使用makefile运行modelsim进行混合编译

modelsim的图像界面加载缓慢&#xff0c;实际上modelsim可以在纯命令行环境下仿真&#xff0c;使用-c参数:vsim -c。可以在WSL下用makefile运行Windows下的modelsim&#xff1a; HDL_CODE . HDL_CODE ../../rtl/ MODELSIM_ROOT : /mnt/e/exe/modeltech64_10.4/win…...

idea 常用插件和常用快捷键 - 记录

idea 常用插件 记得下载插件完成后&#xff0c;点击 Apply 和 OK Alibaba Java Coding Guidelines 作用&#xff1a;使用该插件可以&#xff0c;自动提示相关的语法格式问题&#xff0c;格式参考 阿里巴巴代码规范 详情链接&#xff1a; 代码规范之Alibaba Java Coding G…...

IDEA报错:Plugin ‘org.springframework.boot:spring-boot-maven-plugin:‘ not found

问题&#xff1a; 使用IDEA新建spring boot项目&#xff0c;报错如下&#xff1a; Plugin org.springframework.boot:spring-boot-maven-plugin: not found解决办法&#xff1a; 1.在本地maven仓库中找到spring-boot-maven-plugin的版本号 2.在pom.xml文件中添加对应的版本…...

C++——Vector:push_back和emplace_back的区别,测试写入1GB大数据时的性能差距

什么是emplace_back emplace_back是C11引入的STL容器成员函数。emplace操作只执行构造而不执行拷贝构造。 如何理解上面这句话&#xff1f;先来看一个场景。 class test { public:test(){}test(int i){ std::cout << "test(int i)" << std::endl; }tes…...

C/C++/QT/Python/MATLAB获取文件行数的示例

1. C获取文件行数 #include <stdio.h>int main() {FILE *file fopen("path/to/your/file.txt", "r");if (file NULL) {printf("Failed to open the file!\n");return 0;}int lineCount 0;char ch;while ((ch fgetc(file)) ! EOF) {if…...

mysql的binlog參數詳解

mysql的binlog參數詳解 1. expire_logs_days expire_logs_days&#xff1a;這個參數用於設置binlog日誌文件的過期時間。默認情況下&#xff0c;binlog文件永不過期。如果將其設置為一個正整數值&#xff0c;則表示binlog文件在指定天數後會被自動刪除。 max_binlog_size m…...

【SpringSecurity】九、Base64与JWT

文章目录 1、base64编码2、Base64Url3、JWT的产生背景4、JWT介绍5、JWT组成5.1 Header5.2 Payload5.3 Signature 6、JWT的使用方式7、JWT的几个特点 1、base64编码 base64是一种编码方式&#xff0c;不是加密方式。 所谓Base64&#xff0c;就是说选出64个字符&#xff1a;小写…...

Python的io模块

io 模块提供了 Python 用于处理各种 I/O 类型的主要工具。三种主要的 I/O类型分别为: 文本 I/O, 二进制 I/O 和 原始 I/O。 io.open() 是内置的 open() 函数的别名. 语法&#xff1a; open(file,moder,buffering-1,encodingNone,errorsNone,newlineNone,closefdTrue,openerN…...

CSS---flex布局

主要记录flex布局的要点以及实例 flex flex父标签的6个属性flex-direction: flex布局的方向flex-wrap: 是否可以换行flex-flow: flex-direction 和 flex-wrap 一起写justify-content&#xff1a;横向对齐方式align-items: 纵向对齐方式align-content: 有换行情况下的纵向对齐方…...

java线程和go协程

一、线程的实现 线程的实现方式主要有三种&#xff1a;内核线程实现、用户线程实现、用户线程加轻量级进程混合实现。因为自己只对java的线程比较熟悉一点&#xff0c;所以主要针对java线程和go的协程之间进行一个对比。 线程模型主要有三种&#xff1a;1、内核级别线程&#…...

JAVA 时间戳

时间戳&#xff08;Timestamp&#xff09;是一个表示特定时间点的数值&#xff0c;通常指的是自某个固定的起始时间&#xff08;如1970年1月1日00:00:00 UTC&#xff09;以来经过的秒数或毫秒数。 在 Java 中&#xff0c;可以使用 System.currentTimeMillis() 方法获取当前的时…...

层次分析法(matlab实现)

1.层次分析法&#xff08;AHP&#xff09; 在决策理论中&#xff0c;层次分析法是一种以数学和心理学为基础&#xff0c;组织和分析复杂决策的结构化技术&#xff0c;它代表了一种量化决策标准权重的准确方法&#xff0c;通过成对比较&#xff0c;利用个别专家的经验来估计因素…...

python selenium 自动化登录页面

去掉自动化标识&#xff0c;绕过js&#xff0c;绕过ip import time from selenium import webdriver from selenium.webdriver.chrome.options import Options# 去掉自动化标识&#xff0c;绕过js option Options() option.add_experimental_option(excludeSwitches, [enable…...

【Linux】高级IO --- 多路转接,select,poll,epoll

所有通过捷径所获取的快乐&#xff0c;无论是金钱、性还是名望&#xff0c;最终都会给自己带来痛苦 文章目录 一、五种IO模型1.什么是高效的IO&#xff1f;&#xff08;降低等待的时间比重&#xff09;2.有哪些IO模型&#xff1f;哪些模型是高效的&#xff1f;3.五种IO模型的特…...

anaconda navigator打不开,一直在loading画面

anaconda navigator打不开&#xff0c;一直在loading画面。百度解决方法&#xff0c;用网上的方法在命令窗口里运行conda update anaconda结果一直显示 solving environment卡在那里。又尝试用管理员身份运行还是不行&#xff0c;打开后出现There in aninstance of Anaconda Na…...

【Java基础】深入理解反射、反射的应用(工厂模式、代理模式)

文章目录 1. Java反射机制是什么&#xff1f;1.2 Java反射例子 2. Java反射机制中获取Class的三种方式及区别&#xff1f;3. Java反射机制的应用场景有哪些&#xff1f;3.1. 优化静态工厂模式&#xff08;解耦&#xff09;3.1.1 优化前&#xff08;工厂类和产品类耦合&#xff…...

VUE 项目 nginx部署

server {listen 80; # 监听的端口号server_name 129.204.189.149; # 服务器的ip或者域名#charset koi8-r;#access_log logs/host.access.log main;# 前端服务反向代理配置location / {proxy_http_version 1.1;proxy_set_header Host $host;proxy_set_header X-Real-…...

Hashtable和HashMap、ConcurrentHashMap 之间的区别

Hashtable和HashMap的区别 HashMap和Hashtable都是哈希表数据结构&#xff0c;但是Hashtable是线程安全的&#xff0c;HashMap是线程不安全的 Hashtable实现线程安全就是简单的把关键方法都加上了synchronized关键字 直接在方法上添加synchronized相当于针对this对象&#xff0…...

包管理工具--》npm的配置及使用(二)

在阅读本篇文章前请先阅读包管理工具--》npm的配置及使用&#xff08;一&#xff09; 目录 &#x1f31f;语义版本 避免还原的差异 npm的差异版本处理 &#x1f31f;npm 脚本 &#xff08;npm scripts&#xff09; &#x1f31f;运行环境配置 在node中读取package.json …...

【Linux】多线程2——线程互斥与同步/多线程应用

文章目录 1. 线程互斥1.1 问题引入1.2 线程互斥的相关概念1.3 互斥量mutex1.4 互斥量实现原理1.5 死锁 2. 线程安全和可重入函数3. 线程同步3.1 同步概念3.2 条件变量 4. 生产消费模型4.1 基于阻塞队列的cp模型4.2 基于环形队列的cp模型POSIX信号量 5. 线程池5.1 互斥量RAII版本…...

Python中的函数式编程是什么?

Python中的函数式编程是一种编程范式&#xff0c;它强调使用纯函数和避免可变状态来构建程序。函数式编程的核心思想是将计算视为函数的求值&#xff0c;而不是通过改变状态来实现。在函数式编程中&#xff0c;函数被视为一等公民&#xff0c;可以作为参数传递给其他函数&#…...