網站首頁 編程語言 正文
IO模型
io_service對象是asio框架中的調度器,所有異步io事件都是通過它來分發處理的(io對象的構造函數中都需要傳入一個io_service對象)。
asio::io_service io_service;
asio::ip::tcp::socket socket(io_service);
在asio框架中,同步的io主要流程如下:
應用程序調用IO對象成員函數執行IO操作
IO對象向io_service 提出請求.
io_service 調用操作系統的功能執行連接操作.
操作系統向io_service 返回執行結果.
io_service將錯誤的操作結果翻譯為boost::system::error_code類型,再傳遞給IO對象.
如果操作失敗,IO對象拋出boost::system::system_error類型的異常.
而異步IO的處理流程則有些不同:
應用程序調用IO對象成員函數執行IO操作
IO對象請求io_service的服務
io_service 通知操作系統其需要開始一個異步連接.
操作系統指示連接操作完成, io_service從隊列中獲取操作結果
應用程序必須調用io_service::run()以便于接收結果
調用io_service::run()后,io_service返回一個操作結果,并將其翻譯為error_code,傳遞到事件回調函數中
io_service對象
io_service對象主要有兩個方法——post和run:
post用于發布io事件,如timer,socket讀寫等,一般由asio框架相應對象調用,無需我們顯式調用。
run用于監聽io事件響應,并執行響應回調,對于異步io操作需要在代碼中顯式調用,對于同步io操作則由io對象隱式調用(并不是run函數,不過也是等待io事件)。
可見,io_service提供的是一個生產者消費者模型。在異步io操作中需要我們手動控制消費者,調用run函數,它的基本工作模式如下:
等待io事件響應,如果所有io事件響應完成則退出
等待到io事件響應后,執行其對應的回調
繼續等待下一個io事件,重復1-2
從中可以看出,io_service是一個工作隊列的模型。在使用過程中一般有如下幾個需要注意的地方:
1. run函數在io事件完成后會退出,導致后續基于該對象的異步io任務無法執行
由于io_service并不會主動常見調度線程,需要我們手動分配,常見的方式是給其分配一個線程,然后執行run函數。但run函數在io事件完成后會退出,線程會終止,后續基于該對象的異步io任務無法得到調度。
解決這個問題的方法是通過一個asio::io_service::work對象來守護io_service。這樣,即使所有io任務都執行完成,也不會退出,繼續等待新的io任務。
boost::asio::io_service?io;
boost::asio::io_service::work?work(io);
io.run();
2. 回調在run函數的線程中同步執行,當回調處理時間較長時阻塞后續io響應
解決這個問題的方法有兩種:1. 啟動多線程執行run函數(run函數是線程安全的),2. 新啟動一個線程(或通過線程池)來執行回調函數。一般來講,如果回調處理事件不是特別短,應該使用在線程池中處理回調的方式。
3. 回調在run函數的線程中同步執行,io事件較多的時候得不到及時響應
這個其實是性能問題了,在多核cpu上可以通過在多個線程中執行run函數來解決這一問題。這種方式也只能充分利用cpu性能,本身性能問題就不是光靠軟件就能解決的。
.net中的異步io調度方式
和io_service這種手動控制的方式比起來,.net則是純粹的自動檔了。IO調度由CLR托管了,無需手動控制。回調也是在線程池中執行,無需擔心影響后續IO響應。
正是由于CLR的托管,在.net 的異步IO框架中,就沒有類似io_service的調度對象存在,這也符合.net的一貫簡潔做法。
原文鏈接:https://www.cnblogs.com/TianFang/archive/2013/02/02/2890366.html
相關推薦
- 2022-12-04 Flutter狀態管理Provider的使用示例詳解_Android
- 2023-03-18 C#?DataTable.Select()根據條件篩選數據問題_C#教程
- 2024-03-18 bootstrap application 和 nacos 中配置文件的優先級
- 2022-11-14 python中的運算符
- 2022-08-14 Android?中TextureView和SurfaceView的屬性方法及示例說明_Android
- 2022-11-30 GoLang?channel底層代碼分析詳解_Golang
- 2022-05-13 Linux操作系統筆記——GCC編譯器
- 2022-03-15 antd-mobile 請求時Loading組件
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支