Proactor设计模式:单线程高并发

Boost::Asio为同步和异步操作提供了并行支持,异步支持基于前摄器模式,这种模式的优点和缺点可能比只同步或反应器方法要低。
让我们检查一下Boost::Asio是如何实现前摄器模式的,没有引用基于平台的细节。
前摄器设计模式,改编自POSA2
--异步操作
定义一个异步执行的操作,比如socket的异步读和异步写。
--异步操作处理器
执行异步操作并在操作完成的时候把事件入队到一个完成事件队列,stream_socket_service等服务可以抽象成异步操作处理器。
--完成事件队列
缓存完成事件直到他们被异步事件分解器取出队列。
--完成句柄
处理异步操作的结果,是函数对象,经常使用boost::bind创建。
--异步事件多路分解器
阻塞等待完成事件队列,直到有事件发生,并返回一个完成事件给调用者。
--前摄器
调用异步事件分解器来把事件出队列,并且分发给同事件关联的完成句柄(调用函数对象),这个抽象层的代表是io_service层。
--发起者
应用程序的代码启动了异步操作,发起者通过一个抽象的接口来和异步操作处理器交互,比如basic_stream_socket,轮流提供类似于stream_socket_service的服务。
使用Reactor的实现
在许多平台,Boost::Asio依照Reactor的方式实现Proactor,比如select、epoll、kqueue,下列方法符合Proactor的设计模式:
--异步操作处理器
一个使用select、epoll、kqueue实现的Reactor,当Reactor指示资源已经准备好执行操作,处理器执行操作并把完成时间队列关联的完成句柄入队列。
--完成事件队列
完成句柄的列表(函数对象)。
--异步事件多路分解器
等待事件或者条件变量直到完成事件队列的完成句柄可用。
使用windows平台overlapped I/O实现
在windowsNT、2000或者xp,Boost::Asio利用overlapped的优势来实现有效的Protacor模式,下列是符合Proactor模式的方法:
--异步操作处理器
操作系统提供支持,通过调用AcceptEx之类的操作来发起操作。
--完成事件队列
操作系统提供支持,并和I/O完成端口关联起来,
--异步事件多路分解器
被Boost::Asio调用来出队列事件和他们的关联完成句柄。
优势
--可移植的
许多操作系统支持一个原生的异步I/O API作为高性能网络开发的推荐操作,这些库可能依据原生异步I/O的实现,然而,如果原生API不可用,这些库也可能使用典型Reactor模式的异步事件多路分解器来实现,比如POSIX select()。
--从并发中解耦线程
耗时长的操作被应用程序异步执行,因此应用程序不需要启动大量线程来提高并发
--性能和扩展性
某些实现策略会降低系统性能,比如每个线程一个连接,因为增加了CPU间的上下文切换、同步、数据移动,通过异步操作可以避免或者减少上下文切换开销-最小化操作系统的线程-限制资源-只激活有事件要处理的控制线程。
--简单的应用同步
异步完成句柄就像是在一个单线程环境写入,因此应用程序开发过程中可以少考虑或者不考虑同步问题。
--函数构成
函数构成依据函数的实现来提高更高抽象的操作,比如发送一个特定格式的消息,每个函数多次调用来完成较低抽象的读、写操作。
例如,一个协议的每个消息包含一个定长的消息头和变长的消息体,消息体的长度被消息头指定,一种假设是用两个低抽象的读、写操作完成消息的读取,第一个接收消息头,一旦消息长度确定,第二个接收整个消息。
为了写作异步模式的函数,异步操作可以被连接起来,也就是说,一个操作上的完成端口可以启动另外一个,启动链条的第一个可以被包装起来,调用者不需要知道高级抽象操作作为一个异步操作的链条来实现。
这种编写方式简化了开发者在网络库上的高层抽象,比如为了支持某种协议而开发函数。
劣势
--编程复杂性
使用异步模式开发应用程序更加困难,因为从时间和空间来看启动和完成被分割开来,因为控制流反转应用程序更难被调试。
--内存使用
在读、写期间内存是一直占用的,这会带来不确定性,在每个并发的时候需要一个单独的buffer,而Reactor模式,在读、写就绪前并不需要缓存空间。
参考文献
[POSA2] D. Schmidt et al, Pattern Oriented Software Architecture, Volume 2. Wiley, 2000. 

转载于:https://www.cnblogs.com/learn-my-life/p/5268424.html

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

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

相关文章

一、scrapy爬虫框架——概念作用和工作流程 scrapy的入门使用

scrapy的概念和流程 学习目标: 了解 scrapy的概念了解 scrapy框架的作用掌握 scrapy框架的运行流程掌握 scrapy中每个模块的作用 1. scrapy的概念 Scrapy是一个Python编写的开源网络爬虫框架。它是一个被设计用于爬取网络数据、提取结构性数据的框架。 Scrapy 使…

LeetCode 2285. 道路的最大总重要性

文章目录1. 题目2. 解题1. 题目 给你一个整数 n ,表示一个国家里的城市数目。城市编号为 0 到 n - 1 。 给你一个二维整数数组 roads ,其中 roads[i] [ai, bi] 表示城市 ai 和 bi 之间有一条 双向 道路。 你需要给每个城市安排一个从 1 到 n 之间的整…

二、scrapy爬虫框架——scrapy构造并发送请求

scrapy数据建模与请求 学习目标: 应用 在scrapy项目中进行建模应用 构造Request对象,并发送请求应用 利用meta参数在不同的解析函数中传递数据 1. 数据建模 通常在做项目的过程中,在items.py中进行数据建模 1.1 为什么建模 定义item即提前…

LeetCode 2287. 重排字符形成目标字符串

文章目录1. 题目2. 解题1. 题目 给你两个下标从 0 开始的字符串 s 和 target 。你可以从 s 取出一些字符并将其重排,得到若干新的字符串。 从 s 中取出字符并重新排列,返回可以形成 target 的 最大 副本数。 示例 1: 输入:s &…

Python自动化办公——xlrd、xlwt读写Excel

一、xlrd、xlwt读写Excel 1、读操作 import xlrd# 1、打开工作本workbook xlsx xlrd.open_workbook(r.\7月下旬入库表.xlsx)# 2、打开需要操作的表sheet table xlsx.sheet_by_index(0) # table xlsx.sheet_by_name(7月下旬入库表)# 3、读取指定单元格的数据 print(table.c…

LeetCode 2288. 价格减免

文章目录1. 题目2. 解题1. 题目 句子 是由若干个单词组成的字符串,单词之间用单个空格分隔,其中每个单词可以包含数字、小写字母、和美元符号 $ 。 如果单词的形式为美元符号后跟着一个非负实数,那么这个单词就表示一个价格。 例如 "$…

UWP滑动后退

经过近些年智能手机App的不断发展,用户已经不仅仅满足于功能上的需求。UI、设计等非功能点逐渐在App体验中占了大多数的分数。不知从何时起,滑动手势就成为了App的一个标配。他不仅仅是一个功能,更是一个UI设计。其有以下几个优点&#xff1a…

PyQt5 高级界面控制(表格、树、tab、dock、scrollbar、多文档界面)

文章目录1. 表格与树1.1 QTableView1.2 QListView1.3 QListWidget1.4 QTableWidget表根据界面宽度自动伸缩禁止编辑单击某单元,使之默认选中整行设置宽高度与内容相匹配是否显示表头单元格中放置控件输入行号,快速定位行设置颜色加粗字体排序文本对齐合并…

使用pymysql进行数据库的增删改查

使用pymysql进行数据库的增删改查: import pymysqldatabase pymysql.connect(127.0.0.1,root,root,jxgl,charsetutf8)# 初始化指针 cursor database.cursor()# 增 # sql "insert into students(s_no,s_name,sex,birthday,D_NO,address,phone) VALUES (1230…

PyQt5 高级界面控制(多线程、网页交互、调用JavaScript)

文章目录1. 多线程1.1 QTimer1.2 QThread界面卡住例子分离UI和工作线程1.3 事件处理2. 网页交互显示本地 html显示 html 代码调用 JavaScriptJavaScript 调用 PyQt代码learn from 《PyQt5 快速开发与实战》 https://doc.qt.io/qtforpython/index.html https://www.riverbankcom…

读写Excel 用 xlsxwriter,openpyxl 更灵活

一、xlsxwriter的使用: # import xlwt # # workbook xlwt.Workbook() # sheet0 workbook.add_sheet(sheet0) # for i in range(0,300): # sheet0.write(0,i,i) # workbook.save(number.xls)# 以上代码运行会报错,因为xlwt不支持超过256列的表格im…

LeetCode 2293. 极大极小游戏

文章目录1. 题目2. 解题1. 题目 给你一个下标从 0 开始的整数数组 nums ,其长度是 2 的幂。 对 nums 执行下述算法: 设 n 等于 nums 的长度,如果 n 1 ,终止 算法过程。否则,创建 一个新的整数数组 newNums &#x…

LeetCode 2294. 划分数组使最大差为 K

文章目录1. 题目2. 解题1. 题目 给你一个整数数组 nums 和一个整数 k 。你可以将 nums 划分成一个或多个 子序列 ,使 nums 中的每个元素都 恰好 出现在一个子序列中。 在满足每个子序列中最大值和最小值之间的差值最多为 k 的前提下,返回需要划分的 最…

LeetCode 2295. 替换数组中的元素

文章目录1. 题目2. 解题1. 题目 给你一个下标从 0 开始的数组 nums ,它包含 n 个 互不相同 的正整数。请你对这个数组执行 m 个操作,在第 i 个操作中,你需要将数字 operations[i][0] 替换成 operations[i][1] 。 题目保证在第 i 个操作中&a…

LeetCode 2296. 设计一个文本编辑器(双栈)

文章目录1. 题目2. 解题1. 题目 请你设计一个带光标的文本编辑器,它可以实现以下功能: 添加:在光标所在处添加文本。删除:在光标所在处删除文本(模拟键盘的删除键)。移动:将光标往左或者往右移…

五、scrapy爬虫框架——logging 模块的使用

logging 模块的使用 1、scrapy settings中设置LOG_LEVEL“WARNING”settings中设置LOG_FILE"./a.log"#设置日志保存的位置,设置会后终端不会显示日志内容import logging,实例化logger的方式在任何文件中使用logger输出内容 2、普通项目中 import logg…

PyQt5 布局管理(水平、垂直、网格、表单、嵌套、QSplitter)

文章目录1. 布局管理2. 使用绝对位置布局3. QBoxLayoutaddStretch() 添加可伸缩控件4. QGridLayout5. QFormLayout6. 嵌套布局7. QSplitter 布局learn from 《PyQt5 快速开发与实战》 https://doc.qt.io/qtforpython/index.html https://www.riverbankcomputing.com/static/Doc…

一、Java 面向对象高级——Object类、常用API

day01【Object类、常用API】 主要内容 Object类Date类DateFormat类Calendar类System类StringBuilder类包装类 教学目标 -[ ] 能够说出Object类的特点 -[ ] 能够重写Object类的toString方法 -[ ] 能够重写Object类的equals方法 -[ ] 能够使用日期类输出当前日期 -[ ] 能够使…

FineUI(专业版)v3.0.0 发布,手机、平板和桌面全支持!

FineUI(专业版)v3.0.0 已经正式发布,全面支持手机、平板和桌面!自 2008 年 4 月发布第一个版本,我们持续更新了 126 个版本,拥有 16000 多位注册用户,1300 多位捐赠会员,200 多位网友…

二、Java 面向对象高级——Collection、泛型

day02【Collection、泛型】 主要内容 Collection集合迭代器增强for泛型 教学目标 能够说出集合与数组的区别 说出Collection集合的常用功能 能够使用迭代器对集合进行取元素 能够说出集合的使用细节 能够使用集合存储自定义类型 能够使用foreach循环遍历集合 能够使用泛型定…