一、程式
先來了解一下作業系統的程式:
作業系統對正在執行程式的抽象,這個就是程式(process)。
比如執行一個 web 瀏覽器,一個 text 文字,都是執行的一個一個程式。
有的人說:程式是程式執行資源的集合。程式是系統資源分配的最小單位等等。
從靜態的角度來說,程式確實是執行程式的各種資源集合。
如果你進一步思考,程式裡的各種資源都有哪些呢?如下圖所示:
(圖1:程式資源)
記憶體管理相關
檔案系統
排程相關
訊號處理
核心棧
程式各種狀態
程式執行時統計資訊
程式標識
等等。
可以看出,程式中的資源是相當多的。
從 Linux 作業系統對程式的定義也可以看出。我以前對程式結構 task_struct 分析文章:Linux程式: task_struct結構體成員
多程式:作業系統有多個程式執行,那麼就有多個程式,如下所示簡圖:
(圖2:多程式簡圖)
二、執行緒
2.1 什麼是執行緒?
《作業系統設計與實現》裡說:
在傳統作業系統中,每個程式中只存在一個地址空間和一個控制流(thread)。
然後,有些情況下,需要在相同地址空間中有多個控制流並行的執行,就像他們是單獨的程式一樣(只是他們共享相同的地址空間)。
這些控制流通常被稱為執行緒(thread),有時也稱為輕量級程式(lightweight process)。
儘管執行緒必須在程式中執行,但是執行緒和程式是可以分別對待處理的兩個概念。程式用來集合資源,而執行緒是 CPU 排程的實體。
執行緒給程式模型增加的是,允許在同一個程式環境中有多個執行流,這些執行流在很大程度上相對獨立。
也即是說,在程式中,程式執行的最小單位(執行流)是執行緒,可以把執行緒看作是程式裡的一條執行流。
一個程式裡可以有一條或多條執行緒。
(圖3:程式裡的執行緒)
2.2 為什麼會有多執行緒?
在一個應用程式執行過程中,應用程式裡可能會有多種事件執行。
而有些事件執行一段時間後可能會被阻塞。如果把應用程式執行事件分解成多個並行執行的執行緒,即可以讓程式設計變得簡單,如果有阻塞的,
可以把這部分讓出行換其他執行緒執行。
還有一個原因是:
執行緒比程式更輕量級。所以執行緒比程式更加容易建立,銷燬。
第三個跟第一個有點關係,是關於效能的,若多執行緒都是 CPU 密集型的,那麼不能獲取效能上增強。如果有大量計算和大量 I/O 處理,那麼
多執行緒就可以獲取效能上的優勢,因為允許多執行緒重疊執行。
多執行緒的缺點:
- 對於多執行緒來說,程式中的資源是共享的,所以會產生資源競爭。
- 當程式中的一個執行緒崩潰了,會導致這個程式裡的其他執行緒也崩潰。所以有時多程式程式更好,一個程式崩潰不會導致其他程式也崩潰。
三、程式與執行緒區別
從上面程式和執行緒介紹知道,執行緒是程式執行流的最小單位,程式是作業系統分配資源的單位。
程式與程式之間關係:
程式與程式之間是相互獨立的。
執行緒與程式關係:
執行緒是程式裡的執行流,程式裡的執行緒可以是一個,也可以是多個。
所有執行緒共享程式裡一些資源,比如程式碼,資料,地址空間,訊號處理,開啟檔案,全域性變數等。
同時,執行緒也有自己的暫存器,程式計數器,堆疊,執行緒狀態等
(圖4:程式與執行緒關係)
四、協程
協程是建立線上程之上,一般是語言級別的 ”多執行緒“ 模型,比執行緒更加的輕量級。有的叫它微執行緒。它是完全執行在使用者態裡。
協程是線上程之上在進行抽象,它需要執行緒來承載執行。一個執行緒可以有多個協程。
比如 Go 語言的 goroutine,它用一個關鍵字 go
就可以執行一個協程程式。
在 Go 語言裡面,協程是由 Go 提供的 runtime 來控制和排程。
協程的優點:
-
協程棧很小,只有幾KB,而執行緒棧是 1 M,對比起來,建立大量協程需要的記憶體更少。
-
協程的排程是語言提供的 runtime 來排程,是在使用者空間直接排程,不需要在核心空間和使用者空間來回切換,浪費效率。
-
能更好的利用 cpu 的多核,提高程式執行效能。
-
避免阻塞,如果協程所在的執行緒發生了阻塞,那麼協程排程器可以把執行在阻塞執行緒上的協程,排程到其它沒有發生阻塞的執行緒上,繼續執行。
五:協程與執行緒區別
- 協程是執行線上程之上,一個執行緒可以有多個協程。就像一個程式裡可以有多個執行緒一樣。
- 協程能更好的控制利用多核機制。比如 Go 協程可以控制執行在多少個 CPU 的核上。
- 協程是在使用者空間完成排程,由語言提供的 runtime 進行排程完全使用者態。執行緒由核心排程。
- 協程使用記憶體更小。
六、參考
- 《作業系統設計與實現》作者: (美)ANDREW S.TANENBAUM / ALBERT S.WOODHULL
- https://www.zhihu.com/question/20511233 協程有哪些好處
- https://zh.wikipedia.org/wiki/行程 程式
- https://zh.wikipedia.org/wiki/執行緒 執行緒
- https://zh.wikipedia.org/wiki/協程 協程