溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

boost.asio框架系列之調(diào)度器io_service怎么使用

發(fā)布時(shí)間:2022-06-20 09:27:02 來(lái)源:億速云 閱讀:217 作者:iii 欄目:開(kāi)發(fā)技術(shù)

本篇內(nèi)容介紹了“boost.asio框架系列之調(diào)度器io_service怎么使用”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

IO模型

io_service對(duì)象是asio框架中的調(diào)度器,所有異步io事件都是通過(guò)它來(lái)分發(fā)處理的(io對(duì)象的構(gòu)造函數(shù)中都需要傳入一個(gè)io_service對(duì)象)。

asio::io_service io_service;
asio::ip::tcp::socket socket(io_service);

在asio框架中,同步的io主要流程如下:

boost.asio框架系列之調(diào)度器io_service怎么使用

  • 應(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的處理流程則有些不同:

boost.asio框架系列之調(diào)度器io_service怎么使用

  • 應(yīng)用程序調(diào)用IO對(duì)象成員函數(shù)執(zhí)行IO操作

  • IO對(duì)象請(qǐng)求io_service的服務(wù)

  • io_service 通知操作系統(tǒng)其需要開(kāi)始一個(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讀寫(xiě)等,一般由asio框架相應(yīng)對(duì)象調(diào)用,無(wú)需我們顯式調(diào)用。

  • run用于監(jiān)聽(tīng)io事件響應(yīng),并執(zhí)行響應(yīng)回調(diào),對(duì)于異步io操作需要在代碼中顯式調(diào)用,對(duì)于同步io操作則由io對(duì)象隱式調(diào)用(并不是run函數(shù),不過(guò)也是等待io事件)。

可見(jiàn),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ì)列的模型。在使用過(guò)程中一般有如下幾個(gè)需要注意的地方:

1. run函數(shù)在io事件完成后會(huì)退出,導(dǎo)致后續(xù)基于該對(duì)象的異步io任務(wù)無(wú)法執(zhí)行

由于io_service并不會(huì)主動(dòng)常見(jiàn)調(diào)度線程,需要我們手動(dòng)分配,常見(jiàn)的方式是給其分配一個(gè)線程,然后執(zhí)行run函數(shù)。但run函數(shù)在io事件完成后會(huì)退出,線程會(huì)終止,后續(xù)基于該對(duì)象的異步io任務(wù)無(wú)法得到調(diào)度。

解決這個(gè)問(wèn)題的方法是通過(guò)一個(gè)asio::io_service::work對(duì)象來(lái)守護(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í)間較長(zhǎng)時(shí)阻塞后續(xù)io響應(yīng)

解決這個(gè)問(wèn)題的方法有兩種:1. 啟動(dòng)多線程執(zhí)行run函數(shù)(run函數(shù)是線程安全的),2. 新啟動(dòng)一個(gè)線程(或通過(guò)線程池)來(lái)執(zhí)行回調(diào)函數(shù)。一般來(lái)講,如果回調(diào)處理事件不是特別短,應(yīng)該使用在線程池中處理回調(diào)的方式。

3. 回調(diào)在run函數(shù)的線程中同步執(zhí)行,io事件較多的時(shí)候得不到及時(shí)響應(yīng)

這個(gè)其實(shí)是性能問(wèn)題了,在多核cpu上可以通過(guò)在多個(gè)線程中執(zhí)行run函數(shù)來(lái)解決這一問(wèn)題。這種方式也只能充分利用cpu性能,本身性能問(wèn)題就不是光靠軟件就能解決的。

.net中的異步io調(diào)度方式

和io_service這種手動(dòng)控制的方式比起來(lái),.net則是純粹的自動(dòng)檔了。IO調(diào)度由CLR托管了,無(wú)需手動(dòng)控制?;卣{(diào)也是在線程池中執(zhí)行,無(wú)需擔(dān)心影響后續(xù)IO響應(yīng)。

正是由于CLR的托管,在.net 的異步IO框架中,就沒(méi)有類似io_service的調(diào)度對(duì)象存在,這也符合.net的一貫簡(jiǎn)潔做法。

“boost.asio框架系列之調(diào)度器io_service怎么使用”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI