翻譯 非同步I O不會建立新的執行緒

2022-02-21 06:41:01 字數 1804 閱讀 1575

這是非同步程式設計最基本的事實 :非同步i/o不會建立新的執行緒

反對這個事實的人很多,他們對此的看法是 "如果我await乙個操作,那麼一定會有乙個執行緒正在等待,它可能是乙個執行緒池的執行緒,或者是作業系統執行緒,或者是某個裝置的驅動程式"

不用關注這些看法, 只需要記住如果非同步操作是純粹的(方法全是async),那麼就不會產生新的執行緒

不過這麼乙個簡單的結論顯然並不能夠讓他們信服,下面就看看非同步到底發生了什麼

讓我們跟蹤乙個非同步操作直到硬體層面,注:net部分和裝置驅動部分將被簡化描述 (因為細節太多了)

下面是乙個通用的寫入操作 (例如 檔案、網路、usb麵包機等等)

private async void button_click(object sender, routedeventargs e)

我們已經知道在await的時候ui執行緒不會被阻塞,那麼問題來了: 是否是ui執行緒建立了另外乙個執行緒殺了祭天換來了自己的自由....

關於ui執行緒是否犯下這一惡行,讓我們深入推斷一下

然後作業系統會告訴裝置驅動程式進行寫操作,**實現是構造出表示寫請求的物件,這個物件稱為i/o請求包(irp)

裝置驅動程式接收到irp後會向裝置發出乙個命令來寫出資料,如果這個裝置支援直接記憶體訪問技術(dma),只需將緩衝區位址寫入裝置暫存器即可,裝置驅動程式能做到將irp標記為 "pending" 後交把控制權交還作業系統

在這裡發現了真相的核心所在 : 在處理irp時,裝置驅動是不允許阻塞的。這意味著如果irp不能立即完成,那麼它必須非同步處理,即使對於同步的api也是如此!在裝置驅動級別,所有(有意義)的請求都是非同步的

引用書籍裡的知識 "無論是什麼型別的i/o請求,應用程式向驅動程式發出的i/o操作都是非同步執行的"

在irp為 "pending" 時,作業系統返回到類庫,類庫將未完成的任務返回到應用程式的按鈕單擊事件方法,該方法掛起async方法,ui執行緒繼續執行

我們已經跟蹤請求到系統的盡頭 直到物理裝置

現在寫入操作正在飛快的進行中,有多少個執行緒正在處理它?

答案是沒有

沒有裝置驅動程式執行緒、作業系統執行緒、bcl執行緒或者寫在處理寫操作的執行緒池執行緒(

「多執行緒IO」和「單執行緒非同步IO」的對比

順手寫了個程式對比了一下多執行緒io和單執行緒非同步io的效能差異。需要說明的是,linux上目前的非同步io是由使用者態執行緒模擬的。目前核心原生的aio和glibc中的非同步io都有缺陷,libeio目前感覺比較好 因為nodejs在用 單執行緒非同步io指的是主線程中控制io的 全部都是在主線...

非同步執行緒無法多次建立的問題

最近在做安卓程式過程中,寫了乙個按鈕走秒的messagebox控制項,走秒的實現是用非同步執行緒asynctask實現的,具體如下public class timerdisplay extends asynctask override protected void doinbackground vo...

分布式系統中的非同步IO與執行緒池

分布式搜尋系統中,一般都有merge和search兩種角色,分別部署在不同的機器上。由於資料量巨大,每台search只能載入部分索引資料,多台search機器合在一起組成全量索引。乙個查詢為了獲得正確結果,需要把這個查詢發給所有的search機器,經過檢索後,再把所有search機器的結果聚合在一起...