執行緒 協程 程式
程式
程式是系統資源分配的最小單位, 系統由一個個程式(程式)組成 一般情況下,包括文字區域(text region)、資料區域(data region)和堆疊(stack region)。
- 文字區域儲存處理器執行的程式碼
- 資料區域儲存變數和程式執行期間使用的動態分配的記憶體;
- 堆疊區域儲存著活動過程呼叫的指令和本地變數。
因此程式的建立和銷燬都是相對於系統資源,所以是一種比較昂貴的操作。 程式有三個狀態:
- 等待態:等待某個事件的完成;
- 就緒態:等待系統分配處理器以便執行;
- 執行態:佔有處理器正在執行。
程式是搶佔式的爭奪CPU執行自身,而CPU單核的情況下同一時間只能執行一個程式的程式碼,但是多程式的實現則是通過CPU飛快的切換不同程式,因此使得看上去就像是多個程式在同時進行.
通訊問題: 由於程式間是隔離的,各自擁有自己的記憶體記憶體資源, 因此相對於執行緒比較安全, 所以不同程式之間的資料只能通過 IPC(Inter-Process Communication) 進行通訊共享.
執行緒
- 執行緒屬於程式
- 執行緒共享程式的記憶體地址空間
- 執行緒幾乎不佔有系統資源 通訊問題: 程式相當於一個容器,而執行緒而是執行在容器裡面的,因此對於容器內的東西,執行緒是共同享有的,因此執行緒間的通訊可以直接通過全域性變數進行通訊,但是由此帶來的例如多個執行緒讀寫同一個地址變數的時候則將帶來不可預期的後果,因此這時候引入了各種鎖的作用,例如互斥鎖等。
同時多執行緒是不安全的,當一個執行緒崩潰了,會導致整個程式也崩潰了,即其他執行緒也掛了, 但多程式而不會,一個程式掛了,另一個程式依然照樣執行。
- 程式是系統分配資源的最小單位
- 執行緒是CPU排程的最小單位
- 由於預設程式內只有一個執行緒,所以多核CPU處理多程式就像是一個程式一個核心
執行緒和程式的上下文切換
程式切換分3步:
- 切換頁目錄以使用新的地址空間
- 切換核心棧
- 切換硬體上下文
而執行緒切換隻需要第2、3步,因此程式的切換代價比較大
協程
- 協程是屬於執行緒的。協程程式是線上程裡面跑的,因此協程又稱微執行緒和纖程等
- 協沒有執行緒的上下文切換消耗。協程的排程切換是使用者(程式設計師)手動切換的,因此更加靈活,因此又叫使用者空間執行緒.
- 原子操作性。由於協程是使用者排程的,所以不會出現執行一半的程式碼片段被強制中斷了,因此無需原子操作鎖。
協程的實現:迭代器和生成器
- 迭代器: 實現了迭代介面的類,介面函式例如:current,key,next,rewind,valid。迭代器最基本的規定了物件可以通過next返回下一個值,而不是像陣列,列表一樣一次性返回。語言實現:在Java的foreach遍歷迭代器對(陣列),Python的for遍歷迭代器物件(tuple,list,dist)。
- 生成器: 使用 yield 關鍵字的函式,可以多次返回值,生成器實際上也算是實現了迭代器介面(協議)。即生成器也可通過next返回下一個值。
協程舉例:在Python中,使用了yield的函式為生成器函式,即可以多次返回值。則生成器可以暫停一下,轉而執行其他程式碼,再回來繼續執行函式往下的程式碼。
個人部落格 地址