深入理解并發/并行,阻塞/非阻塞,同步/異步

1. 阻塞,非阻塞

首先,阻塞這個詞來自操作系統的線程/進程的狀態模型中,如下圖:

進程狀態

一個線程/進程經歷的5個狀態,創建,就緒,運行,阻塞,終止。各個狀態的轉換條件如上圖,其中有個阻塞狀態,就是說當線程中調用某個函數,需要IO請求,或者暫時得不到競爭資源的,操作系統會把該線程阻塞起來,避免浪費CPU資源,等到得到了資源,再變成就緒狀態,等待CPU調度運行。

定義:
阻塞調用是指調用結果返回之前,調用者會進入阻塞狀態等待。只有在得到結果之后才會返回。
非阻塞調用是指在不能立刻得到結果之前,該函數不會阻塞當前線程,而會立刻返回。

阻塞調用:比如 socket 的 recv(),調用這個函數的線程如果沒有數據返回,它會一直阻塞著,也就是 recv() 后面的代碼都不會執行了,程序就停在 recv() 這里等待,所以一般把 recv() 放在單獨的線程里調用。

非阻塞調用:比如非阻塞socket 的 send(),調用這個函數,它只是把待發送的數據復制到TCP輸出緩沖區中,就立刻返回了,線程并不會阻塞,數據有沒有發出去 send() 是不知道的,不會等待它發出去才返回的。

拓展

如果線程始終阻塞著,永遠得不到資源,于是就發生了死鎖
比如A線程要X,Y資源才能繼續運行,B線程也要X,Y資源才能運行,但X,Y同時只能給一個線程用(即互斥條件)用的時候其他線程又不能搶奪。
A 有 X,等待 Y。
B 有 Y,等待 X。
于是A,B發生了循環等待,造成死鎖。給用戶的感覺就是程序卡著不動了。
在寫代碼的時候要特別注意共享資源的使用,用信號量控制好,避免造成死鎖。死鎖的解除有個著名的銀行家算法

阻塞和掛起:阻塞是被動的,比如搶不到資源。掛起是主動的,線程自己調用 suspend() 把自己退出運行態了,某些時候調用 resume() 又恢復運行。

線程執行完就會被銷毀,如果不想線程被頻繁的創建,銷毀,怎么辦?可以給線程里面寫個死循環,或者讓線程有任務的時候執行,沒任務的時候掛起,就像iOS中的 runloop 機制一樣。線程就不會隨便的終止了。


2. 同步,異步

定義
同步:在發出一個同步調用時,在沒有得到結果之前,該調用就不返回。
異步:在發出一個異步調用后,調用者不會立刻得到結果,該調用就返回了。

同步例子

int n = func();
next();
// func() 的結果沒有返回,next() 就不會執行,直到 func() 運行完。

異步例子

func(callback);
next();
...

void callback(int n)     // func 結果回調
{
  int k = n;
}
// func() 執行后,還沒得出結果就立即返回,然后執行 next() 了
// 等到結果出來,func() 回調 callback() 通知調用者結果。

同步的定義看起來跟阻塞很像,但是同步跟阻塞是兩個概念,同步調用的時候,線程不一定阻塞,調用雖然沒返回,但它還是在運行狀態中的,CPU很可能還在執行這段代碼,而阻塞的話,它就肯定不在CPU中跑這個代碼了。這就是同步和阻塞的區別。同步是肯定可以在,阻塞是肯定不在。

異步和非阻塞的定義比較像,兩者的區別是異步是說調用的時候結果不會馬上返回,線程可能被阻塞起來,也可能不阻塞,兩者沒關系。非阻塞是說調用的時候,線程肯定不會進入阻塞狀態。

上面兩組概念,就有4種組合。
同步阻塞調用:得不到結果不返回,線程進入阻塞態等待。
同步非阻塞調用:得不到結果不返回,線程不阻塞一直在CPU運行。
異步阻塞調用:去到別的線程,讓別的線程阻塞起來等待結果,自己不阻塞。
異步非阻塞調用:去到別的線程,別的線程一直在運行,直到得出結果。


3. 并發,并行

先從定義說起,定義經過我通俗化了,原定義有點難理解。

并發是指一個時間段內,有幾個程序都在同一個CPU上運行,但任意一個時刻點上只有一個程序在處理機上運行。

并行是指一個時間段內,有幾個程序都在幾個CPU上運行,任意一個時刻點上,有多個程序在同時運行,并且多道程序之間互不干擾。

兩者區別如下圖

并行是多個程序在多個CPU上同時運行,任意一個時刻可以有很多個程序同時運行,互不干擾。

并發是多個程序在一個CPU上運行,CPU在多個程序之間快速切換,微觀上不是同時運行,任意一個時刻只有一個程序在運行,但宏觀上看起來就像多個程序同時運行一樣,因為CPU切換速度非常快,時間片是64ms(每64ms切換一次,不同的操作系統有不同的時間),人類的反應速度是100ms,你還沒反應過來,CPU已經切換了好幾個程序了。

切換耗時:線程用完了時間片,釋放CPU控制權,引發系統中斷,調度程序根據相關策略選取下一個線程來運行,這里需要一點耗時。

舉個例子吧,并行就是,多個人,有人在掃地,有人在做飯,有人在洗衣服,掃地,做飯,洗衣服都是同時進行的。
并發就是,有一個人,這個人一會兒掃地,一會兒做飯,一會兒洗衣服,他在這3件事中來回做,同一時刻只做一件事,不是同時做的,但最后3件事都可以做完。

  • 時間片大小的選取

時間片取的小,假設是20ms,切換耗時假設是 10ms。
那么用戶感覺不到多個程序之間會卡,響應很快,因為切換太快了,但是CPU的利用率就低了,20 / (20 + 10) = 66% 只有這么多,33%都浪費了。

時間片取的大,假設是200ms,切換耗時是 10ms
那么用戶會覺得程序卡,響應慢,因為要200ms后才輪到我的程序運行,但是CPU利用率就高了,200 / (200 + 10) = 95% 有這么多被利用的。

所以時間片取太大或者太小都不好,一般在 10 - 100 ms 之間。

  • CPU調度策略

在并發運行中,CPU需要在多個程序之間來回切換,那么如何切換就有一些策略

3.1 先來先服務 - 時間片輪轉調度
這個很簡單,就是誰先來,就給誰分配時間片運行,缺點是有些緊急的任務要很久才能得到運行。

3.2 優先級調度
每個線程有一個優先級,CPU每次去拿優先級高的運行,優先級低的等等,為了避免優先級低的等太久,每等一定時間,就給優先級低的線程提高一個級別

3.3 最短作業優先
把線程任務量排序,每次拿處理時間短的線程運行,就像我去銀行辦業務一樣,我的事情很快就處理完了,所以讓我插隊先辦完,后面時間長的人先等等,時間長的人就很難得到響應了。

3.4 最高響應比優先
用線程的等待時間除以服務時間,得到響應比,響應比小的優先運行。這樣不會造成某些任務一直得不到響應。

3.5 多級反饋隊列調度
有多個優先級不同的隊列,每個隊列里面有多個等待線程。
CPU每次從優先級高的遍歷到低的,取隊首的線程運行,運行完了放回隊尾,優先級越高,時間片越短,即響應越快,時間片大小就不是固定的了。
每個隊列的內部還是用先來先服務的策略。

最后發個以前寫的模擬CPU調度的程序(下載地址

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,182評論 6 543
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,489評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,290評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,776評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,510評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,866評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,860評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,036評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,585評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,331評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,536評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,058評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,754評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,154評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,469評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,273評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,505評論 2 379

推薦閱讀更多精彩內容