網(wǎng)站首頁 編程語言 正文
IO模型
io_service對(duì)象是asio框架中的調(diào)度器,所有異步io事件都是通過它來分發(fā)處理的(io對(duì)象的構(gòu)造函數(shù)中都需要傳入一個(gè)io_service對(duì)象)。
asio::io_service io_service;
asio::ip::tcp::socket socket(io_service);
在asio框架中,同步的io主要流程如下:
應(yīng)用程序調(diào)用IO對(duì)象成員函數(shù)執(zhí)行IO操作
IO對(duì)象向io_service 提出請(qǐng)求.
io_service 調(diào)用操作系統(tǒng)的功能執(zhí)行連接操作.
操作系統(tǒng)向io_service 返回執(zhí)行結(jié)果.
io_service將錯(cuò)誤的操作結(jié)果翻譯為boost::system::error_code類型,再傳遞給IO對(duì)象.
如果操作失敗,IO對(duì)象拋出boost::system::system_error類型的異常.
而異步IO的處理流程則有些不同:
應(yīng)用程序調(diào)用IO對(duì)象成員函數(shù)執(zhí)行IO操作
IO對(duì)象請(qǐng)求io_service的服務(wù)
io_service 通知操作系統(tǒng)其需要開始一個(gè)異步連接.
操作系統(tǒng)指示連接操作完成, io_service從隊(duì)列中獲取操作結(jié)果
應(yīng)用程序必須調(diào)用io_service::run()以便于接收結(jié)果
調(diào)用io_service::run()后,io_service返回一個(gè)操作結(jié)果,并將其翻譯為error_code,傳遞到事件回調(diào)函數(shù)中
io_service對(duì)象
io_service對(duì)象主要有兩個(gè)方法——post和run:
post用于發(fā)布io事件,如timer,socket讀寫等,一般由asio框架相應(yīng)對(duì)象調(diào)用,無需我們顯式調(diào)用。
run用于監(jiān)聽io事件響應(yīng),并執(zhí)行響應(yīng)回調(diào),對(duì)于異步io操作需要在代碼中顯式調(diào)用,對(duì)于同步io操作則由io對(duì)象隱式調(diào)用(并不是run函數(shù),不過也是等待io事件)。
可見,io_service提供的是一個(gè)生產(chǎn)者消費(fèi)者模型。在異步io操作中需要我們手動(dòng)控制消費(fèi)者,調(diào)用run函數(shù),它的基本工作模式如下:
等待io事件響應(yīng),如果所有io事件響應(yīng)完成則退出
等待到io事件響應(yīng)后,執(zhí)行其對(duì)應(yīng)的回調(diào)
繼續(xù)等待下一個(gè)io事件,重復(fù)1-2
從中可以看出,io_service是一個(gè)工作隊(duì)列的模型。在使用過程中一般有如下幾個(gè)需要注意的地方:
1. run函數(shù)在io事件完成后會(huì)退出,導(dǎo)致后續(xù)基于該對(duì)象的異步io任務(wù)無法執(zhí)行
由于io_service并不會(huì)主動(dòng)常見調(diào)度線程,需要我們手動(dòng)分配,常見的方式是給其分配一個(gè)線程,然后執(zhí)行run函數(shù)。但run函數(shù)在io事件完成后會(huì)退出,線程會(huì)終止,后續(xù)基于該對(duì)象的異步io任務(wù)無法得到調(diào)度。
解決這個(gè)問題的方法是通過一個(gè)asio::io_service::work對(duì)象來守護(hù)io_service。這樣,即使所有io任務(wù)都執(zhí)行完成,也不會(huì)退出,繼續(xù)等待新的io任務(wù)。
boost::asio::io_service?io;
boost::asio::io_service::work?work(io);
io.run();
2. 回調(diào)在run函數(shù)的線程中同步執(zhí)行,當(dāng)回調(diào)處理時(shí)間較長時(shí)阻塞后續(xù)io響應(yīng)
解決這個(gè)問題的方法有兩種:1. 啟動(dòng)多線程執(zhí)行run函數(shù)(run函數(shù)是線程安全的),2. 新啟動(dòng)一個(gè)線程(或通過線程池)來執(zhí)行回調(diào)函數(shù)。一般來講,如果回調(diào)處理事件不是特別短,應(yīng)該使用在線程池中處理回調(diào)的方式。
3. 回調(diào)在run函數(shù)的線程中同步執(zhí)行,io事件較多的時(shí)候得不到及時(shí)響應(yīng)
這個(gè)其實(shí)是性能問題了,在多核cpu上可以通過在多個(gè)線程中執(zhí)行run函數(shù)來解決這一問題。這種方式也只能充分利用cpu性能,本身性能問題就不是光靠軟件就能解決的。
.net中的異步io調(diào)度方式
和io_service這種手動(dòng)控制的方式比起來,.net則是純粹的自動(dòng)檔了。IO調(diào)度由CLR托管了,無需手動(dòng)控制。回調(diào)也是在線程池中執(zhí)行,無需擔(dān)心影響后續(xù)IO響應(yīng)。
正是由于CLR的托管,在.net 的異步IO框架中,就沒有類似io_service的調(diào)度對(duì)象存在,這也符合.net的一貫簡潔做法。
原文鏈接:https://www.cnblogs.com/TianFang/archive/2013/02/02/2890366.html
相關(guān)推薦
- 2022-11-17 一文詳解測試Python讀寫xml配置文件_python
- 2023-07-26 TypeScript中的模塊與命名空間
- 2023-10-16 Nginx啟動(dòng),重啟以及基本命令
- 2022-02-17 Centos 安裝docker 警告:正在等候 事務(wù) 鎖定 arb/rpm/.rpm.lock 正在
- 2022-05-27 C++?超詳細(xì)深入分析單例模式_C 語言
- 2022-08-02 Android開發(fā)自定義雙向SeekBar拖動(dòng)條控件_Android
- 2022-06-02 深入解析Apache?Hudi內(nèi)核文件標(biāo)記機(jī)制_服務(wù)器其它
- 2022-07-18 Linux文件權(quán)限
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支