線程,進程,協程, 併發,並行,同步,異步概念解析

我相信線程,進程,協程, 併發,並行,同步,異步這幾個概念大家在編程過程中肯定會遇到,但是偏偏這幾個概念又那麼類似,很容易讓人模糊,今天我就用這一篇文章來和大家梳理一下這幾個概念。

1. 同步與異步

  • 當我們 同步 的執行某個任務時,我們需要等到這個任務執行完給我們反饋結果,我們才能去執行其他的任務。
  • 但是 異步 的執行某個任務時,我們可以不用等這個任務結束就去執行另一項任務。就像常用到的異步刷新操作。通過異步執行的任務執行結束後我們可以通過 回調函數 獲得結果。

我們可以明顯的看出同步和異步的差別,那異步操作那麼好為什麼不都使用異步操作呢?同步操作存在的意義是有些任務必須是 按順序執行 的,就像我們去銀行取錢,最起碼的保證你的銀行賬戶裡有錢你才能取,要不然豈不是去搶銀行了:full_moon_with_face:。

2. 併發與並行

2.1 併發 Concurrency

咱們用做早飯來舉例,例如說你還沒起床,你的女朋友已經早早的起來了,在廚房給你準備早飯,她想給你做一份麵包片和煎蛋,她為了能讓你儘快的吃上早飯,開了兩個鍋,一個鍋用來煎蛋,一個鍋用來煎麵包片,但是她為了食物儘可能美味,只能看一下煎蛋的鍋,在去看一下烤麵包片,這樣

每個鍋看一分鐘,來回切換 ,這樣終於把麵包片和煎蛋做好了,這時你也睡醒了,吃到了美味的早餐。

你女朋友的這個做早飯的流程就是併發操作,因為她不可能同時將注意力放在兩個鍋上,只能通過逐漸切換注意力的方式來使任務很好的完成。但是如果你的女朋友可以在兩個鍋之間切換的足夠快:joy:,在旁邊看起來就像是她在同時操作兩個鍋 。

2.2 並行 Parallelism

咱們還是用做早餐為例,現在你和你的女朋友在一起已經很久了,她再也受不了天天早上給你做飯的日子了,所以今天早上她把你也拽起來和她一起做飯。同樣還是煎麵包片和煎蛋,這時你和你女朋友一份一個鍋,你在準備煎蛋,你的女朋友在煎麵包片,你倆就這樣很和諧的做著自己的事互不干擾,很快就吃到了美味的早餐。

你和你的女朋友同時做飯,每個人操作一個鍋的方式就是並行操作。

ps:突然將你想到了,原來自己沒有女朋友 。

2.3 圖解併發與並行

假設我們有兩個任務A和B,我們使用併發執行是這樣的。

線程,進程,協程, 併發,並行,同步,異步概念解析

可以看到雖然A和B作為兩個整體的任務但是未必會直接執行完,而是會在兩個任務間來回切換。因為cpu切換的速度實在太快了,所以我們看起來好像是A和B在同時執行,但其實在每個時間點上只有一個任務在執行。

我們再來看一下並行的方式。

線程,進程,協程, 併發,並行,同步,異步概念解析

並行操作是指兩個任務同時執行的。

3. 進程,線程與協程

3.1 進程 Process

電腦中每個軟件的啟動就代表一個進程,就是把寫的程序加載到操作系統中來執行預定好的任務。操作系統會為進程分配相應的資源來支撐它完成任務,每個進程會分配一個唯一的PID。

線程,進程,協程, 併發,並行,同步,異步概念解析

我們這次用老王來舉例,假如說老王現在想蓋個房子,我們就可以把蓋房子這件事作為一個任務,而老王就是負責這個任務的進程。

3.2 線程 Thread

線程是進程的執行實例,是一個程序執行的最小單元,每個進程裡的任務會有線程去具體執行。

線程,進程,協程, 併發,並行,同步,異步概念解析

我們還是繼續說老王,現在蓋房子這個任務已經確定下來了,但是他發現自己不會蓋,要請個工人來蓋房子,於是他去外面請了一個工人A,這個工人A要做搬磚和搬木頭的工作,此時這個工人A就是一個

進程 ,老王還要求他這兩個任務不能差距太大,要同步進行,所以這個工人A只能搬一趟轉頭,搬一趟木頭,這樣的操作就是 單線程的併發操作

幹了兩天,工人A不高興了乾的活太多了要加錢,這時老王一看一個人幹也確實慢,就去外面又請了一個工人B,此時工人B也就對應著一個 線程 ,老王讓工人A繼續搬磚,而工人B來負責搬木頭,這樣兩個任務就能同時進行了,這就是 多線程的並行操作 。而且此時工人A和工人B是同時 共享著老王提供的資源

3.3 進程與線程+單核與多核

其實剛才老王那個例子已經能解釋進程與線程的操作了,但是有些不太謹慎。

  • 如果我們使用的是 單核CPU ,那麼我們是無法執行並行操作的,只能做到併發,這樣來充分調用CPU的資源。
  • 如果我們使用的是 多核CPU ,我們才可以真正的意義上做到並行操作。

我們的操作系統在進程或線程間切換是比較消耗資源的,因為要保存當前運行狀態的上下文信息,而且進程或線程的切換是由操作系統決定的,到達運行時間之後,操作系統會將當前執行的任務掛起,我們只能等待下個分配到的時間片來繼續執行任務。這也就引出來協程的概念。

3.4 協程 Coroutine

就像我們剛才說到的,任務的切換是操作系統來控制,我們有沒有什麼辦法來減小這種開銷呢?我們就可以使用協程, 協程我們可以理解為輕量級的線程 。 協程在執行過程中不會由操作系統直接操作,而是由編譯器決定,比如協程A說我當前的任務還得一段時間執行完,我可以讓出當前佔用的資源了,協程A就會通知調度器,由調度器來分配下一個協程執行。


分享到:


相關文章: