深入理解同步和异步与reactor和proactor模式

devtools/2024/12/22 22:00:34/

在现代网络编程中,I/O 设计模式对于提高性能和资源利用率至关重要。本文将探讨两种主要的网络 I/O 设计模式:同步 I/O 和异步 I/O,以及它们的实现方式。

同步 I/O

同步 I/O 模式要求用户通过系统调用函数,如 read(), write(), connect() 等,将网络数据从内核态拷贝到用户态的缓冲区,或者从用户态拷贝到网卡缓冲区。这个过程涉及到用户态和内核态之间的数据拷贝,可能会占用较多的 CPU 时间。同步调用的特点是在数据传输过程中,用户线程会被阻塞,直到数据传输完成。

a97d64744e284c5488719480802241a3.png

异步 I/O

与同步 I/O 不同,异步 I/O 允许用户线程直接使用内核态的数据,无需手动读取。这意味着数据在内核态与用户态的传输已经由内核完成,用户态可以直接对数据进行业务处理。

Reactor 模式

Reactor 模式是一种常见的同步I/O 模式,通常与多路复用技术(如 epoll)结合使用。其工作流程大致如下:

  1. 初始化 epoll 对象和监听 socket。
  2. 将 socket 文件描述符(fd)注册到 epoll 对象,并调用多路复用函数 epoll_wait()
  3. 根据 epoll_wait() 返回的事件类型,由工作线程进行 I/O 操作。

Proactor 模式

Proactor 模式是异步 I/O 的一种实现方式,它与 Reactor 模式的主要区别在于它是异步的。在 Proactor 模式中,用户不需要关心读写就绪事件,只需要关注读写完成事件。数据在内核态与用户态的传输已经由内核完成,业务进程只需要在用户态处理结果即可。

一个典型的 Proactor 模式实现是 Boost ASIO 库,它提供众多异步函数,比如 async_read ,允许用户指定缓冲区和回调函数,当内核完成数据接收后,会自动调用回调函数。

Linux 与 Windows 的比较

在 Linux 下,目前没有系统级别的接口直接支持 Proactor 模式,而 Windows 的 IOCP(I/O 完成端口)提供了这种支持。因此,在 Windows 上实现 Proactor 模式的程序效率可能会略高于 Linux。在 Linux 上,Proactor 模式的实现通常是模拟 IOCP 的过程。

Proactor 模式的实现流程

下图是asio官方给的Proactor 实现结构图

72fa206e1cc94cd2bfefb26b266ff0cb.jpeg

涉及以下几个关键组件:

  1. Asynchronous Operation(异步操作):类似于 read、write 等系统调用。
  2. Asynchronous Operation Processor(异步操作处理器):监听读写就绪事件并执行异步操作,然后将读写完成事件的通知插入到完成事件队列。
  3. Completion Event Queue(完成事件队列):存放完成事件。
  4. Asynchronous Event Demultiplexer(异步事件多路分离器):监听完成事件队列,如果有完成事件,则调用完成事件处理器。
  5. Completion Handler(完成事件处理器):用户的回调函数。

总结来说,ASIO 的 Proactor 模式实现基本上是在 Reactor 模式的基础上,将 I/O 读写操作封装起来,在内部完成,并通过新增的完成事件队列触发用户绑定的回调函数。

 


http://www.ppmy.cn/devtools/120114.html

相关文章

javacv FFmpegFrameGrabber 阻塞重连解决方法汇总

JavaCV中FrameGrabber类可以连接直播流地址, 进行解码, 获取Frame帧信息, 常用方式如下 FrameGrabber grabber new FrameGrabber("rtsp:/192.168.0.0"); while(true) {Frame frame grabber.grabImage();// ... } 在如上代码中, 若连接地址网络不通, 或者连接超时…

特殊的 BASE64 1

这个一看题目就是base64编码表被改了. 知识点: Base64编码使用一个包含64个字符的字符集,这些字符分别是: 大写字母A-Z小写字母a-z数字0-9特殊字符和/ 这些字符分别对应64个不同的6位二进制数。在补零后形成的8位字节中,实际使用…

爬虫库是什么?是ip吗

爬虫库通常指的是用于网页爬虫(Web Scraping)开发的代码库或框架,它不是IP地址。以下是关于爬虫库的详细解释: 爬虫库的定义 爬虫库是一些用于简化网络数据抓取过程的工具和框架,通常提供了一系列函数和类&#xff0…

SpringCloud源码:服务端分析(二)- EurekaServer分析

背景 从昨日的两篇文章:SpringCloud源码:客户端分析(一)- SpringBootApplication注解类加载流程、SpringCloud源码:客户端分析(二)- 客户端源码分析。 我们理解了客户端的初始化,其实…

OpenCV视频I/O(10)视频采集类VideoCapture之从视频流中检索一帧图像函数 retrieve()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 解码并返回已抓取的视频帧。 cv::VideoCapture::retrieve() 是 VideoCapture 类的一个成员函数,用于从视频流中检索一帧图像。 retr…

【递归】9. leetcode 104 二叉树的最大深度

1 题目描述 题目链接:二叉树的最大深度 2 解答思路 递归分为三步,接下来就按照这三步来思考问题 第一步:挖掘出相同的子问题 (关系到具体函数头的设计) 第二步:只关心具体子问题做了什么 &#xff0…

实现微信小程序中点击单词显示在input的交互功能指南

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…

JMeter压测HTTPS 在window 11处理SSL证书认证

在此位置,找到chrome 的证书 证书到出到指定的路径, 利用jdk中的keytool.exe工具,重新生成证书 crm 去到命令窗口,再去到JDK路径下,如下 输入 keytool -import -alias “zhengshu.store” -file “D:\Program F…