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

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

在现代网络编程中,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.kler.cn/news/319820.html

相关文章:

  • 【递归】5.leetcode 872 叶子相似的树
  • 南开大学联合同济大学发布最新SOTA Occ OPUS:使用稀疏集进行占据预测,最快实现8帧22FPS
  • 什么是服务器日志,日志有什么作用?
  • 2-103 基于matlab的光电信号下血氧饱和度计算
  • Unity3D URP 内置CSM分帧详解
  • 【渗透测试】-灵当CRM系统-sql注入漏洞复现
  • 传输层协议 —— TCP协议(下篇)
  • Spring IoC DI 之 属性注入
  • BottomNavigationView 添加角标
  • c++开发实战之网络编程(一)
  • 三维重建的几何评价指标
  • 面试算法题精讲:求数组两组数差值和的最大值
  • 只出现一次的数字 II
  • Redis:事务
  • Hive 的窗口函数 详解
  • 代码随想录算法训练营| 454.四数相加II 、 383. 赎金信 、 15. 三数之和 、 18. 四数之和
  • 有威胁的武器武装检测系统源码分享
  • WebGL渲染与创建2D内容
  • 树——数据结构
  • 移动端如何实现智能语音交互
  • 【LGR-200-Div.4】洛谷入门赛 #27 A - H题解,包含(C++, Go语言)
  • Mybatis中sql数组为空判断
  • SpringBoot 整合docker,执行容器服务
  • Qt系统相关——事件
  • JavaScript --模版字符串用反引号
  • Qt (19)【Qt 线程安全 | 互斥锁QMutex QMutexLocker | 条件变量 | 信号量】
  • python学习笔记(3)——控制语句
  • Java获取Object中Value的方法
  • 数据结构-3.链表
  • 无人机在隧道中如何实现在无卫星信号下的自主导航