boost.asio系列——io_service
IO模型
io_service對象是asio框架中的調度器,所有異步io事件都是通過它來分發處理的(io對象的構造函數中都需要傳入一個io_service對象)。
????asio::io_service?io_service;
????asio::ip::tcp::socket?socket(io_service);
在asio框架中,同步的io主要流程如下:
????
而異步IO的處理流程則有些不同:
????
io_service對象
io_service對象主要有兩個方法——post和run:
可見,io_service提供的是一個生產者消費者模型。在異步io操作中需要我們手動控制消費者,調用run函數,它的基本工作模式如下:
從中可以看出,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的一貫簡潔做法。
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的boost.asio系列——io_service的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 内存管理:_CrtDumpMemoryL
- 下一篇: 详细解析Raid0、Raid0+1、Ra