go語言中執行緒和程序的區別是什麼

2022-12-28 14:00:21

區別:1、執行緒是程式執行的最小單位,而程序是作業系統分配資源的最小單位。2、一個程序由一個或多個執行緒組成,執行緒是一個程序中程式碼的不同執行路線。3、執行緒上下文切換比程序上下文切換要快得多。4、程序切換需要的資源很最大,效率很低;執行緒切換需要的資源一般,效率一般。5、程序擁有自己的堆疊,程序之間不共用堆疊;執行緒擁有自己的棧,共用堆。

本教學操作環境:windows7系統、GO 1.18版本、Dell G3電腦。

什麼是執行緒、程序?

程序

  • 是一個具有一定獨立功能的程式在一個資料集上的一次動態執行過程
  • 是作業系統進行資源分配和排程的一個獨立單位
  • 是應用程式的執行的載體

執行緒

  • 執行緒是程式執行中一個單一的順序控制流程
  • 是程式執行流的最小單位
  • 是處理器排程和分配的基本單位
  • 一個程序可以有一個或多個執行緒
  • 各個執行緒之間共用程式的記憶體空間

任務排程

大部分作業系統(Windows、Linux)的任務排程採用時間片輪轉的搶佔式排程方式
該排程方式如下:

  • 在一個程序中,當一個執行緒任務執行幾毫秒後,會由作業系統核心進行排程

  • 通過硬體的計數器中斷處理器,讓該執行緒強制暫停並將該執行緒的暫存器放入記憶體中

  • 通過檢視執行緒列表決定接下來執行哪一個執行緒

  • 然後從記憶體中恢復該執行緒的暫存器,最後恢復該執行緒的執行,從而去執行下一個任務

這種方式保證了每個執行緒輪流執行,由於CPU的執行效率非常高,時間片非常短,在各個任務之間快速地切換,給人的感覺就是多個任務在同時進行,這就是我們說的並行

1.png

程序和執行緒的區別

  • 執行緒是程式執行的最小單位,而程序是作業系統分配資源的最小單位

  • 一個程序由一個或多個執行緒組成,執行緒是一個程序中程式碼的不同執行路線

  • 執行緒上下文切換比程序上下文切換要快得多

  • 程序切換需要的資源很最大,效率很低;執行緒切換需要的資源一般,效率一般。

  • 程序擁有自己的堆疊,程序之間不共用堆疊,由作業系統排程

    執行緒擁有自己的棧,共用堆,也是由作業系統排程

多執行緒和多核

多核處理器是指在一個處理器上整合了多個運算核心從而提高計算能力。也就是有多個真正平行計算的處理核心,每一個處理核心對應一個核心執行緒。

核心執行緒

每一個處理核心對應一個核心執行緒。
比如:

  • 單核處理器對應一個核心執行緒
  • 雙核處理器對應兩個核心執行緒
  • 四核處理器對應四個核心執行緒

核心執行緒(Kernel Thread,KLT)就是直接由作業系統核心支援的執行緒。該執行緒由核心來完成執行緒切換,核心通過操作排程器對執行緒進行排程,並負責將執行緒的任務對映到各個處理器上。

超執行緒技術

目前處理器都採用了超執行緒技術將一個 物理處理核心模擬成兩個邏輯處理核心,也就是兩個核心執行緒。
所以我們看到的電腦一般都是雙核四執行緒、四核八執行緒。
在作業系統中我們看到CPU數量是實際物理CPU數量的兩倍,如雙核四執行緒可以看到4CPU。

如我當前編寫文章的這臺mbp就是i7 6核12執行緒:

2.png

程式一般不會直接使用核心執行緒,而是使用核心執行緒的一種高階介面—輕量級程序(Lightweight Process,LWP),也就是我們常說的執行緒

協程

協程(Coroutines)基於執行緒之上,比執行緒更加輕量級。一個執行緒可以擁有多個協程。

協程的目的

傳統應用中一般有會給網路請求建立一個執行緒去完成業務邏輯。如果是多個請求,就會建立多個執行緒來出來。
如果遇到很耗時的I/O行為,執行緒就會一直處於阻塞狀態,如果很多執行緒都是出於這種空閒狀態(等待該執行緒執行完成才能執行),這樣就會造成資源應用不徹底,系統的吞吐能力下降。

最常見的很耗時的I/O行為比如JDBC,CPU會一直等待資料I/O操作的返回,這時執行緒根本沒有利用CPU去做運算,而是處於空閒狀態。同時使用過多的執行緒,也會帶來更多的上下文切換開銷。

解決上述問題有兩個方案:

  • 單執行緒加上非同步回撥
    比如Node.js、Java的Vert.x
  • 協程
    協程的目的就是當出現長時間I/O操作時,讓出當前的協程排程,執行下一個任務,來消除ContexSwith的開銷

協程的特點

  • 執行緒切換由作業系統負責排程,協程由使用者自己排程,因此減少了上下文切換,提高了效率
  • 執行緒預設Stack大小為1M,而協程更輕量,接近1K。因此可以在相同的記憶體中開啟更多的協程
  • 由於協程在同一執行緒上,因此可以避免競爭關係二使用鎖
  • 適用於被阻塞且需要大量並行的場景。但不適用於大量計算的多執行緒

協程的原理

協程的流程:

  • 當出現I/O阻塞的時候,由協程的排程器進行排程

  • 通過將資料流立刻yield掉(主動讓出),並記錄當前棧上的資料

  • 阻塞完成後立刻在通過執行緒恢復棧,並把阻塞的結果放到這個執行緒上去跑

而跑在由Coroutine負責排程的執行緒稱為Fiber,比如Golang裡的go關鍵字其實就是負責開啟一個Fiber,讓func邏輯跑在上面。

由於協程的暫停完全由程式控制,發生在使用者態上;而執行緒的阻塞狀態是由作業系統核心來進行切換,發生在核心態上。
因此協程的開銷遠遠小於執行緒,也就沒有上下文切換的開銷。

執行緒和協程的比較

比較項執行緒協程
佔用資源初始單位為1MB,固定不可變初始一般為2KB,可隨需要增大
排程所屬有OS核心完成由使用者完成
切換開銷設計模式切換(從使用者態切換到核心態),16個暫存器、PC、SP等暫存器的重新整理只有三個暫存器的值修改:PC、SP、DX
效能問題資源佔用太高,頻繁建立銷燬會帶來嚴重的效能問題資源佔用小,不會帶來嚴重的效能問題
資料同步需要鎖等機制確保資料的一致性和可見性不需要多執行緒的鎖機制,因此只有一個執行緒。也不存在同時寫變數衝突,在協程中控制共用資源不加鎖,只需要判斷狀態就好了,所以執行效率比執行緒高很多

【相關推薦:Go視訊教學、】

以上就是go語言中執行緒和程序的區別是什麼的詳細內容,更多請關注TW511.COM其它相關文章!