處理併發 非同步非阻塞

2022-04-17 21:21:22 字數 2705 閱讀 5123

在研究nginx和node.js的時候常會遇到非同步、非阻塞等,之前自己也經常使用epoll,對其同步與阻塞,非同步與非阻塞有了一定的認識,現對參考資料總結下。

首先討論下使用事件驅動,非同步程式設計的優點:

充分利用了系統資源,執行**無須阻塞等待某種操作完成,有限的資源可以用於其他的任務。其非常適合於後端的網路服務程式設計。

在伺服器開發中,併發的請求處理是個大問題,阻塞式的函式會導致資源浪費和時間延遲。通過事件註冊、非同步函式,開發人員可以提高資源的利用率,效能也會改善。其nginx和node.js處理併發都是採用的事件驅動非同步非阻塞模式。其中nginx中處理併發用的是epoll,poll,queue等方式,node.js使用的是libev,它們對大規模的http請求處理的都很好。

阻塞《node.js開發指南》是這樣定義的:執行緒在執行中如果遇到(i/o 操作)如磁碟讀寫或網路通訊,通常要耗費較長的時間,這時作業系統會剝奪這個執行緒的 cpu 控制權,使其暫停執行,同時將資源讓給其他的工作執行緒,這種執行緒排程方式稱為 阻塞。當 i/o 操作完畢時,作業系統將這個執行緒的阻塞狀態解除,恢復其對cpu的控制權,令其繼續執行。這種 i/o 模式就是通常的同步式 i/o(synchronous i/o)或阻塞式 i/o(blocking i/o)。

非阻塞非阻塞是這樣定義的,當執行緒遇到 i/o 操作時,不會以阻塞的方式等待 i/o 操作的完成或資料的返回,而只是將 i/o 請求傳送給作業系統,繼續執行下一條語句。當作業系統完成 i/o 操作時,以事件的形式通知執行 i/o 操作的執行緒,執行緒會在特定時候處理這個事件。

對比阻塞與非阻塞

阻塞模式下,乙個執行緒只能處理一項任務,要想提高吞吐量必須通過多執行緒。

非阻塞模式下,乙個執行緒永遠在執行計算操作,這個執行緒所使用的 cpu 核心利用率永遠是 100%,i/o 以事件的方式通知。

在阻塞模式下,多執行緒往往能提高系統吞吐量,因為乙個執行緒阻塞時還有其他執行緒在工作,多執行緒可以讓 cpu 資源不被阻塞中的執行緒浪費。

而在非阻塞模式下,執行緒不會被 i/o 阻塞,永遠在利用 cpu。多執行緒帶來的好處僅僅是在多核 cpu 的情況下利用更多的核。

來看看《深入淺出node.js》對非同步i/o的解釋,在作業系統中,程式執行的空間分為核心空間和使用者空間。我們常常提起的非同步i/o,其實質是使用者空間中的程式不用依賴核心空間中的i/o操作實際完成,即可進行後續任務。

i/o的阻塞與非阻塞的解釋

阻塞模式的i/o會造成應用程式等待,直到i/o完成。同時作業系統也支援將i/o操作設定為非阻塞模式,這時應用程式的呼叫將可能在沒有拿到真正資料時就立即返回了,為此應用程式需要多次呼叫才能確認i/o操作完全完成。

i/o的同步與非同步i/o的同步與非同步出現在應用程式中。如果做阻塞i/o呼叫,應用程式等待呼叫的完成的過程就是一種同步狀況。相反,i/o為非阻塞模式時,應用程式則是非同步的。

參照《node.js入門經典》中對同步的解釋,同步的**意味著每一次執行乙個操作,在乙個操作完成之前,**的執行會被阻塞,無法移到下乙個操作上。也就是說**的執行會在函式返回前停止。直到函式返回後,**才會繼續執行。

相反,非同步就意味著函式的執行無需等待某個操作的結果就可以繼續執行,其操作的結果會在事件發生時由**來處理。

非同步i/o優缺點

使用同步io,它的優點是可以使程式除錯方便,但是它的缺點也是明顯的,程式的執行過程中如果入到一些耗時的io操作,程式的執行都要等待該io的完成,在這個等待的過程中,程式無法充分利用cpu,導致了cpu的閒置,為了充分利用cpu,和io並行操作,常用的方法有2中:

(1)多執行緒單程序

多執行緒的設計之處就是為了在共享的程式空間中,實現並行處理任務,從而達到充分利用cpu的效果。

多執行緒缺點:

其一、執行時(執行緒切換)上下文交換的開銷較大,乙個執行緒大約需要2m的記憶體空間,占用資源較大。

其二、狀態同步(鎖)的問題,它也使得程式的編寫和呼叫複雜化。

(2)單執行緒多程序

為了避免多執行緒造成的使用不便問題,有的語言選擇了單執行緒保持呼叫簡單化,採用啟動多程序的方式來達到充分利用cpu和提公升總體的並行處理能力。它的缺點在於業務邏輯複雜時(涉及多個i/o呼叫),因為業務邏輯不能分布到多個程序之間,事務處理時長要遠遠大於多執行緒模式。

非同步i/o與輪詢技術

當進行非阻塞i/o呼叫時,要讀到完整的資料,應用程式需要進行多次輪詢,才能確保讀取資料完成,以進行下一步的操作。輪詢技術的缺點在於應用程式要主動呼叫,會造成占用較多cpu時間片,效能較為低下。現存的輪詢技術有以下這些: read、select、poll、epoll、pselect、kqueue 

read是效能最低的一種,它通過重複呼叫來檢查i/o的狀態來完成完整資料讀取。

select是一種改進方案,通過對檔案描述符上的事件狀態來進行判斷。

作業系統還提供了poll、epoll等多路復用技術來提高效能。

輪詢技術滿足了非同步i/o確保獲取完整資料的保證。但是對於應用程式而言,它仍然只能算時一種同步,因為應用程式仍然需要主動去判斷i/o的狀態,依舊花費了很多cpu時間來等待。上一種方法重複呼叫read進行輪詢直到最終成功,使用者程式會占用較多cpu,效能較為低下。而實際上作業系統提供了select方法來代替這種重複read輪詢進行狀態判斷。select內部通過檢查檔案描述符上的事件狀態來進行判斷資料是否完全讀取。但是對於應用程式而言它仍然只能算是一種同步,因為應用程式仍然需要主動去判斷i/o的狀態,依舊花費了很多cpu時間等待,select也是一種輪詢。

理想的非同步i/o模型

理想的非同步i/o應該是應用程式發起非同步呼叫,而不需要進行輪詢,進而處理下乙個任務,只需在i/o完成後通過訊號或是**將資料傳遞給應用程式即可。

併發,同步,非同步,阻塞,非阻塞,執行緒

乙個cpu沒有真正意義的併發,兩個人同時做同樣的事情才是真正意義上的併發,只有統籌分時處理.多路同步 同步,實時處理並且活動按順序執行 非同步,乙個人合理的安排時間來做事情,分時處理,活動分段執行,非順序執行 阻塞模式,等,同步,併發,非同步都有可能會阻塞,只是機率的大小 非阻塞模式 不等 併發,併...

同步非同步?阻塞非阻塞?併發並行?

阻塞呼叫是指呼叫結果返回之前,呼叫者會進入阻塞狀態等待。只有在得到結果之後才會返回。非阻塞呼叫是指在不能立刻得到結果之前,該函式不會阻塞當前執行緒,而會立刻返回。同步 在發出乙個同步呼叫時,在沒有得到結果之前,該呼叫就不返回。非同步 在發出乙個非同步呼叫後,呼叫者不會立刻得到結果,該呼叫就返回了。同...

併發 並行,阻塞 非阻塞,同步 非同步

1.阻塞,非阻塞 乙個執行緒 程序經歷的5個狀態,建立,就緒,執行,阻塞,終止。各個狀態的轉換條件如上圖,其中有個阻塞狀態,就是說當執行緒中呼叫某個函式,需要io請求,或者暫時得不到競爭資源的,作業系統會把該執行緒阻塞起來,避免浪費cpu資源,等到得到了資源,再變成就緒狀態,等待cpu排程執行。定義...