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

【C++】I/O多路转接详解(二)

在上一篇文章【C++】I/O多路转接详解(一)

在出现EPOLL之后,随之而来的是两种事件处理模式的应运而生:Reator 和 Proactor,同步IO模型常用于Reactor模式,异步IO常用于Proactor.

目录

  • 1. 服务器编程框架简介
  • 2. IO处理
    • 1. Reactor模式
    • 2. Proactor模式
      • 2.1 使用异步读写接口实现Proactor
      • 2.2 使用Reactor模拟Proactor
  • 3. 并发模式
    • 3.1 半同步-半异步模式
      • 3.1.1 同步与异步
      • 3.1.2 同步与异步在服务器中的使用
      • 3.1.3 Half-SYNC/Half-Reactive模式
    • 3.2 领导者-追随者模式

1. 服务器编程框架简介

请添加图片描述
无论是对于单服务器架构还是分布式,集群架构,我们都可以将服务器分为四个主要板块:

  1. I/O处理单元
    • 管理用户连接,一般作为接入层(网关)存在
  2. 逻辑单元
    • 一个逻辑单元是一个用于完成业务的进程或者线程,它分析处理用户数据并将结果传给IO处理单元,直接发给客户端。
    • 在集群模式下,一个逻辑单元就是一台逻辑服务器,一般会有多个逻辑单元来进行并行处理任务
  3. 网络存储单元
    • 一般是数据库,缓存,以及文件,或者一台独立服务器。
  4. 请求队列
    • 请求队列是对单元间通信方式的抽象
    • 对于服务集群,请求队列是各台服务器之间预先建立的,静态的,永久的TCP连接。

2. IO处理

这一节,我们要讲解目前最主流的IO处理模式,主流网络库基本都是基于此实现,如libevent,moduo…

1. Reactor模式

Reactor模式要求 主线程(即IO处理单元)只负责监听文件描述符上是否有时间发生,有的话立即将事件通知工作线程(逻辑单元),除此之外,主线程不再做任何事情,读写事件,接受新连接等,这些都在工作线程完成。
请添加图片描述

这里有我实现的一个单进程的同步reactor模型(检测事件就绪 + 对数据读写 + 对数据业务处理),大家可以参考一下:
reactor demo

2. Proactor模式

proactor将所有的IO操作交给主线程和内核来处理,工作线程只负责业务逻辑。

2.1 使用异步读写接口实现Proactor

通常,我们可以使用aio_read来完成proactor,在这种实现方式中,连接socket上的读写事件是通过aio_read/aio_write向内核注册的,因此os kernel将通过信号来向应用程序报告连接socket的读写事件,也就说,主线程中的epoll_wait只能够监听socket上的连接请求事件,无法监视读写事件。
在这里插入图片描述


2.2 使用Reactor模拟Proactor

根据我们之前讲的proactor,关键在于工作线程只负责系统业务,而无需进行对于内核缓冲区的读写,即工作线程直接收到的就是数据包,而不是一个需要处理的事件。

根据这个思路,很容易想到,我们对reactor模式进行一点改动:主线程处理负责事件注册通知外,还需要执行数据的读写操作,读写完成之后,主线程向工作线程通知这一完成事件。那么从工作线程的角度,它们直接获取到了数据。
请添加图片描述

3. 并发模式

并发模式指IO处理单元和多个逻辑单元(多个进程/线程)之间协调完成任务的方法,服务器主要有两种并发编程模式:半同步-半异步模式,领导者-追随者模式。

3.1 半同步-半异步模式

3.1.1 同步与异步

注意,这里的同步异步并不是IO模型中的概念,即就绪事件和完成时间的差别。这里指的是:

  • 异步:程序的执行需要系统事件来驱动,比如:中断,信号。
  • 同步: 程序完全按照代码顺序执行
    在这里插入图片描述

3.1.2 同步与异步在服务器中的使用

对于一个线程来说,同步运行方式叫做同步线程,异步方式运行叫做异步线程。

  • 异步线程执行效率高,但是编写复杂,难以调试,拓展
  • 同步线程执行效率低,但是逻辑简单

对于一个服务器来说,我们既追求实时性,同时又要求并发程度好,因此,我们可以对于不同的部分采用不同的策略:

  • 异步线程用于处理I/O事件,监听到客户请求之后,将其封装为请求对象插入请求队列
  • 同步线程用于工作线程,请求队列(eg:线程池)将会把请求对象分配给同步工作线程
    在这里插入图片描述

3.1.3 Half-SYNC/Half-Reactive模式

基于以上思想,从reactor模式衍生出半同步/半反应堆模式。
在这里插入图片描述

  • 主线程:监听所有socket事件,但是只处理连接事件(即将新连接socket注册为可读事件),将就绪的读写事件写入请求队列。
  • 工作线程:从请求队列中获取就绪事件(连接socket),进行读写…

当然,这种模式不是死板的,也有一些更加高效的变式:

在这里插入图片描述

  • 主线程:值注册监听listen_sock,对于新的连接到来,进行accept建立连接并将返回的连接sock派发给工作线程
  • 工作线程:每个工作线程维护自己的工作线程,将主线程派发的sock注册到自己的事件循环,各自独立监听不同事件。

3.2 领导者-追随者模式

领导者-追随者模式见的并不多,这里简单介绍一下:
熟悉redis主从模式,或者说一些分布式协同算法的同学很快就能联想到,该模式就是使得多个工作线程轮流获取到事件源集合,轮流监听,分发与处理事件的模式。

每个程序的唯一一个领导线程将负责监听IO事件,其他线程暂时休眠。当前的leader thread检测到IO事件,则从线程池中的休眠线程中选出新的leader,然后自己去处理IO事件。


相关文章:

【C++】I/O多路转接详解(二)

在上一篇文章【C】I/O多路转接详解(一) 在出现EPOLL之后,随之而来的是两种事件处理模式的应运而生:Reator 和 Proactor,同步IO模型常用于Reactor模式,异步IO常用于Proactor. 目录 1. 服务器编程框架简介2. IO处理1. R…...

PySpark(三)RDD持久化、共享变量、Spark内核制度,Spark Shuffle

目录 RDD持久化 RDD 的数据是过程数据 RDD 缓存 RDD CheckPoint 共享变量 广播变量 累加器 Spark 内核调度 DAG DAG 的宽窄依赖和阶段划分 内存迭代计算 Spark是怎么做内存计算的? DAG的作用?Stage阶段划分的作用? Spark为什么比MapReduce快? Spar…...

详解MYSQL中的平均值组大小

文章目录 平均值组大小了解平均值组大小MySQL什么时候会使用平均值组大小平均值组大小对于索引选取的影响平均值组大小 了解平均值组大小 总数据量 / 值组 = 平均值组大小 值组是一组具有相同键前缀值的行,及所有相等的键为一个值组。总数据量为全表数据量MySQL什么时候会使…...

【爬虫专区】批量下载PDF (无反爬)

天命:只要没反爬,一切都简单 这次爬取的是绿盟的威胁情报的PDF 先看一下结构,很明显就是一个for循环渲染 burp抓包会发现第二次接口请求 接口请求一次就能获取到了所有的数据 然后一个循环批量下载数据即可,其实没啥难度的 imp…...

PostgreSQL解决序列(自增id)自动增长冲突

背景 一般表的id主键我们都是设置为自增序列。 但是如果我们在插入一些数据的时候手动指定id,那么自增序列不会跟随我们手动设置的id增长。 就会出现下次不设置id的时候自增到我们手动指定的id导致主键冲突bug 举个例子 现在数据有 id123 现在我们手动插入数…...

1.0 Zookeeper 分布式配置服务教程

ZooKeeper 是 Apache 软件基金会的一个软件项目,它为大型分布式计算提供开源的分布式配置服务、同步服务和命名注册。 ZooKeeper 的架构通过冗余服务实现高可用性。 Zookeeper 的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高…...

(Flutter 常用插件整理

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 Flutter 常用插件整理 # Flutter 城市列表,联系人列表,索引&悬停 https://github.com/flutterchina/azlistviewazlistview: ^2.0.0# Dart 汉字转拼音 https://github.com/flutterchina/lpinyinlpinyin…...

vue2.0+使用md-edit编辑器

前言:小刘开发过程中,如果是博客项目一般是会用到富文本。众多富文本中,小刘选择了markdown,并记录分享了下来。 # 使用 npm npm i kangc/v-md-editor -Smain.js基本配置import VueMarkdownEditor from kangc/v-md-editor; import…...

Java设计模式大全:23种常见的设计模式详解(二)

本系列文章简介: 设计模式是在软件开发过程中,经过实践和总结得到的一套解决特定问题的可复用的模板。它是一种在特定情境中经过验证的经验和技巧的集合,可以帮助开发人员设计出高效、可维护、可扩展和可复用的软件系统。设计模式提供了一种在…...

【算法与数据结构】718、1143、1035、392、115、LeetCode最长重复子数组+最长公共子序列+不相交的线+判断子序列+不同的子序列

文章目录 一、718、最长重复子数组二、1143、最长公共子序列三、1035、不相交的线四、392、判断子序列五、115、不同的子序列六、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、718、最长重复子数组 思路分析&#xff1…...

OCR文本纠错思路

文字错误类别:多字 少字 形近字 当前方案 文本纠错思路 简单: 一、构建自定义词典,提高分词正确率。不在词典中,也不是停用词,分成单字的数据极有可能是错字(少部分可能是新词)。错字与前后的…...

【java批量导出pdf】优化方案

问题情境: 项目中存在web页面点击一键导出,导出所有数据对应的pdf文件,由于有些pdf文件是实时生成的,之前最简答的写法for循环处理速度太慢,超过了nginx配置的最大响应时间了,且对用户交互体验上很不友好&…...

Linux第42步_移植ST公司uboot的第3步_uboot命令测试,搭建nfs服务器和tftp服务器

测试uboot命令,搭建nfs服务器和tftp服务器,是测试uboot非常关键的一步。跳过这一节,后面可能要踩坑。 一、输入“help回车”,查询uboot所支持的命令 二、输入“? bootz回车”,查询“bootz”怎么用 注意:和…...

C++枚举算法(3)

我家的门牌号 题目描述&#xff1a; 我家住在一条短胡同里&#xff0c;这条胡同的门牌号从1开始顺序编号。 若所有的门牌号之和减去我家门牌号的两倍&#xff0c;恰好等于n&#xff0c;求 我家的门牌号及总共有多少家。 数据保证有唯一解。 输入 一个正整数n。n < 100000。…...

【51单片机】LED的三个基本项目(LED点亮&LED闪烁&LED流水灯)(3)

前言 大家好吖&#xff0c;欢迎来到 YY 滴单片机系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过单片机的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的…...

Day 17------C语言收尾之链表的删除、位运算、预处理、宏定义

链表 空链表&#xff1a; 注意&#xff1a;函数不能返回局部变量的地址 操作&#xff1a; 1.创建空链表 2.头插 3.尾插 4.链表遍历 5.链表的长度 free&#xff1a;释放 删除&#xff1a; 头删 void popFront(struct Node *head) { //1.p指针变量指向首节点 //2.断…...

python_蓝桥杯刷题记录_笔记_全AC代码_入门5

前言 关于入门地刷题到现在就结束了。 题单目录 1.P1579 哥德巴赫猜想&#xff08;升级版&#xff09; 2.P1426 小鱼会有危险吗 1.P1579 哥德巴赫猜想&#xff08;升级版&#xff09; 一开始写的代码是三重循环&#xff0c;结果提交上去一堆地TLE&#xff0c;然后我就给减少…...

二叉树的详解

二叉树 【本节目标】 掌握树的基本概念掌握二叉树概念及特性掌握二叉树的基本操作完成二叉树相关的面试题练习 树型结构&#xff08;了解&#xff09; 概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。…...

【第三十五节】idea项目的创建以及setting和Project Structure的设置

项目创建 Project Structure的设置 点击file ~ Project Structure 进入...

【c++】跟webrtc学引用计数

rtc::RefCountInterface 接口类 G:\CDN\rtcCli\m98\src\rtc_base\ref_count.h引用计数想形成一种树状结构 // Interfaces where refcounting is part of the public api should // inherit this abstract interface. The implementation of these // methods is usually provid…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

基于IDIG-GAN的小样本电机轴承故障诊断

目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) ​梯度归一化(Gradient Normalization)​​ (2) ​判别器梯度间隙正则化(Discriminator Gradient Gap Regularization)​​ (3) ​自注意力机制(Self-Attention)​​ 3. 完整损失函数 二…...

手机平板能效生态设计指令EU 2023/1670标准解读

手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读&#xff0c;综合法规核心要求、最新修正及企业合规要点&#xff1a; 一、法规背景与目标 生效与强制时间 发布于2023年8月31日&#xff08;OJ公报&…...

在 Spring Boot 中使用 JSP

jsp&#xff1f; 好多年没用了。重新整一下 还费了点时间&#xff0c;记录一下。 项目结构&#xff1a; pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...