同步 非同步 阻塞 非阻塞 I O

2021-09-21 18:07:43 字數 3474 閱讀 8803

一、同步/非同步

首先要是多個事物,只有乙個事物,是不存在同步或非同步的。

同步:指協同步調。即,多個事物不能同時進行,必須乙個乙個的來,上乙個事物結束後,下乙個事物才開始。

那當乙個事物正在進行時,其他事物在幹嘛呢?

嚴格來講並沒有要求,但一般都處於「等待」狀態,因為後面事物的正常進行都需要依賴前面事物的結果或者前面事物正在使用的資源。

因此,可以認為,同步更希望關注的是從巨集觀整體來看,多個事物是一種逐個逐個序列化關係,絕對不會出現交叉的情況。

所以,自然不太會關注某個瞬間某個具體事物是處於乙個什麼狀態(即在幹什麼)。

「排隊」場景可以很好的詮釋這個理論。凡是在資源少需求多的場景下都會應用到排隊。

栗子:排隊買火車票事件

售票大廳更注重的是旅客乙個乙個的到視窗買票,因為一次只能賣一張票,即使大家一窩蜂的圍上去,還是一次只能賣一張票,何必呢?擠在一起又不安全。但是有些人非要硬擠,售票大廳就採用排隊方式來達到自己的目的。

至於在排隊的狀態,是看手機還是說話,根本不關心。

除了這種由於資源導致的同步外,還存在一種由於邏輯上的先後順序導致的同步。

比如,先更新**,然後編譯,接著打包。這些操作由於後乙個操作需要使用前乙個操作的結果,所以只能按照順序乙個乙個的執行。

同步的另2個小點:

範圍,並不需要在全域性範圍內都去同步,只需要在某些關鍵的點執行同步即可。栗子:食堂只有乙個賣飯視窗,肯定是同步的,乙個人買完,另外乙個人再買,但是吃飯就不需要等待前乙個人先吃完,後乙個人才開始吃。這個範圍上不是同步的。

粒度,並不是只有大粒度的事物才有同步,小粒度的事物也有。只不過小粒度的事物同步通常是天然支援的,而大粒度的事物往往需要手工控制。栗子:比如2個執行緒的同步就需要手工處理,但乙個執行緒的2個語句就是天然同步的。

非同步:步調各異。多個事物可以你進行你的,我進行我的,誰都不用管誰,所有事物都在同步進行中。

總而言之,同步就是多個事物不能同時開工,非同步就是多個事物可以同時開工。

注:體會"多個事物":多個執行緒是多個事物,多個方法多個事物,多個語句是多個事物,多個cpu指令是多個事物。等等等

二、阻塞/非阻塞

阻塞:阻礙堵塞,遇到阻礙而造成的不能進行

非阻塞:沒有遇到阻塞而繼續執行

「堵車」 可以很好的詮釋這個理論。

汽車可以正常通行時,就是非阻塞的。一旦堵上了,全部趴窩,一動不動。

因此阻塞關注的是不能動的,非阻塞關注的是可以動的。

不能動的結果就是只能等待,可以動的結果就是繼續前行。

對應的程式裡阻塞意味著停下來等待,非阻塞表明可以繼續向下執行。

阻塞和等待:

等待只是阻塞的乙個***而已,表明隨著時間的流逝,沒有任何有意義的事物發生或者進行。
阻塞的真正含義是你關心的事物由於某些原因無法繼續進行,因此讓你等待。但是你可以做一些其他無關的事物,因為這並不影響你對關係事物的等待。

栗子:在堵車時,你可以幹等。也可以玩手機,聊天或者打遊戲,吃飯。這些都不影響你對堵車的等待。不過你的車必須待在原地。

在計算機裡,是沒有人這麼靈活的,一般阻塞時,選擇幹等,因為這個最容易實現,只要掛起執行緒,讓出cpu即可。在條件滿足時,會重新排程該執行緒。

兩兩組合:

同步/非同步:關注的是能不能同時開工

阻塞/非阻塞:關注的是能不能動

同步阻塞:不能同時開工,也不能動。只有一條小道,一次只能過一輛車,可悲的是還堵上了。

同步非阻塞:不能同時開工,但可以動。只有一條小道,一次只能過一輛車,幸運的是可以正常通行。

非同步阻塞:可以同時開工,但不可以動。有多條路,每條路都可以跑車,可悲的是,所有的路都路上了。

非同步非阻塞:可以同時開工,也可以動。有多條路,每條路都可以跑車,但幸運的是,都可以正常通行。

對應程式裡:

同步阻塞,相當於乙個執行緒在等待。

同步非阻塞,相當於乙個執行緒在正常執行。

非同步阻塞,相當於多個執行緒都在等待。

非同步非阻塞,相當於多個執行緒都在正常執行

三、i/o

io指的是讀入/寫出資料的過程,和等待讀入/寫出資料的過程。一旦拿到資料後就變成資料操作了,就不是io了。

拿網路io來說,等待的過程就是資料從網路到網絡卡再到核心空間。讀寫過程就是核心空間和使用者空間的相互拷貝。

所以io包括2個過程,乙個是等待資料的過程,乙個是讀寫(拷貝)資料的過程。而且還要明白,一定不能包括運算元據的過程。

阻塞io和非阻塞io

應用程式都是執行在使用者空間的,所以它們能操作的資料都在使用者空間,所以只要資料沒有到達使用者空間,使用者執行緒就操作不了。

如果此時使用者執行緒已經參與,那它一定會被阻塞在io上,這就是常說的阻塞io,使用者執行緒被阻塞在等待資料上或者拷貝資料上。

非阻塞io就是使用者執行緒不參與以上2個過程,即資料已經拷貝到使用者空間後,才去通知使用者執行緒,一上來就可以直接運算元據了。

使用者執行緒沒有因為io的事情出現阻塞,這就是常說的非阻塞io。

同步io和同步阻塞io

按照上文中對同步的理解,同步io是指發起io請求後,必須拿到io的資料才可以繼續執行。

按照程式的表現形式又分為2種:

在等待資料的過程中,在拷貝資料的過程中,執行緒都在阻塞,這就是同步阻塞io。

在等待資料的過程中,執行緒採用死迴圈式輪詢,在拷貝資料的過程中,執行緒在阻塞,還是同步阻塞io。有些人認為這是同步非阻塞io,其實不對。

嚴格來講,在io的概念上,同步和非阻塞是不可能搭配的,因為是一對相悖的概念。

同步io意味著必須拿到io的資料,才可以繼續執行。因為後續操作依賴io資料,所以它必須是阻塞的。

非阻塞io意味著發起io請求後,可以繼續往下執行,說明後續執行不依賴於io資料,所以它肯定不是同步的。

因此,在io上,同步和非阻塞是互斥的,所以不存在同步非阻塞io。但同步非阻塞是存在的,那不叫io,叫運算元據了。

所以,同步io一定是阻塞io,同步io也就是同步阻塞io。

非同步io和非同步阻塞/非阻塞io

按照上面對非同步的理解,非同步io指發起io請求後,不用拿到io的資料就可以繼續執行。

使用者執行緒的繼續執行,和作業系統準備io資料的過程是同時進行的,所以才叫非同步io。

按照io資料的兩個過程,又可以分為兩種:

在等待資料的過程中,使用者執行緒繼續執行,在拷貝資料的過程中,執行緒在阻塞,這就是非同步阻塞io。這種情況使用者執行緒沒有參與資料等待的過程,所以是非同步的。但使用者執行緒參與了資料拷貝過程,所以它又是阻塞的。合起來就是非同步阻塞io。

在等待資料的過程中,和拷貝資料的過程中,使用者執行緒都在繼續執行,這就是非同步非阻塞io。這種情況是,使用者執行緒既沒有參與等待過程與拷貝過程,所以是非同步的,當它接到通知時,資料已經準備好了,它沒有因為io資料而阻塞過,所以是非阻塞的,合起來就是非同步非阻塞io。

IO 同步,非同步,阻塞,非阻塞

參考文章 好文推薦 唉最近真是高產似母豬,剛進新公司工作量暫時不飽和,只能每天學學學學學學查漏補缺啦,學習使我快樂哈哈哈哈哈哈哈哈 標題裡的詞彙相信都經常看到,但是能說清楚的估計20個人裡面能有1個就不錯了,網上的資料也是五花八門,大部分描述差不多,很多時候估計作者本身也是似懂非懂,我也看了很多文章...

同步非同步IO,阻塞非阻塞

同步io操作 導致請求程序阻塞,知道io操作完成。非同步io操作 不導致程序阻塞。在處理 網路 io 的時候,阻塞和非阻塞都是同步io,阻塞,就是呼叫我 函式 我 函式 沒有接收完資料或者沒有得到結果之前,我不會返回。非阻塞,就是呼叫我 函式 我 函式 立即返回,通過select通知呼叫者 阻塞與非...

同步IO 非同步IO 阻塞IO 非阻塞IO

同步io 非同步io 阻塞io 非阻塞io,這幾個詞常見於各種各樣的與網路相關的文章之中,往往不同上下文中它們的意思是不一樣的,以致於我在很長一段時間對此感到困惑,所以想寫一篇文章整理一下。posix 可移植作業系統介面 把同步io操作定義為導致程序阻塞直到io完成的操作,反之則是非同步io按pos...