從進程、線程過渡:理解協程


進程

進程是一個程序在一個數據集中的一次動態執行過程,可以理解爲“正在執行的程序”。進程一般由程序集、數據集、進程控制塊三部分組成。進程是系統進行資源分配和調度的基本單位,是操作系統的基礎。進程是線程的容器,進程是程序的實體。

  • 程序集:描述進程要完成哪些功能以及如何完成
  • 數據集:程序在執行過程所需要使用的資源
  • 進程控制塊:保存程序運行的狀態
  • 進程的侷限性是創建、撤銷和切換的開銷比較大。

線程

線程也叫輕量級進程,它是一個基本的CPU執行單元,也是程序執行的最小單位。一個進程最少有一個主線程。

  • 線程的優點:減小了程序併發執行的開銷,提高了系統的併發性能。
  • 線程的缺點:線程沒有自己的系統資源,只有運行時不可缺少的資源,但是同一進程的各線程可以共享進程所擁有的系統資源。對於某些獨佔資源存在鎖機制,處理不當會出現死鎖。

協程

協程是一種用戶態的輕量級線程,又稱微線程。協程的調度完全由用戶控制(進程和線程都是由cpu 內核進行調度)。

  • 協程擁有自己的寄存器上下文和棧。協程調度切換時,將寄存器上下文和棧保存到其他地方,在切回來的時候,恢復先前保存的寄存器上下文和棧,直接操作棧則基本沒有內核切換的開銷,可以不加鎖的訪問全局變量,所以上下文的切換非常快。

  • 對於 進程、線程,都是有內核進行調度,有 CPU 時間片的概念,進行 搶佔式調度(有多種調度算法)
    對於 協程(用戶級線程),這是對內核透明的,也就是系統並不知道有協程的存在,是完全由用戶自己的程序進行調度的,因爲是由用戶程序自己控制,那麼就很難像搶佔式調度那樣做到強制的 CPU 控制權切換到其他進程/線程,通常只能進行 協作式調度,需要協程自己主動把控制權轉讓出去之後,其他協程才能被執行到。

  • 協程的優點:

  1. 協程執行效率高。因爲子程序切換不是線程切換,由程序自身控制,沒有線程切換的開銷。
  2. 協程不需要多線程的鎖機制。在協程中控制共享資源不加鎖,只需要判斷狀態就好

goroutine協程 區別
本質上,goroutine 就是協程。 不同的是,Golang 在 runtime、系統調用等多方面對 goroutine 調度進行了封裝和處理,當遇到長時間執行或者進行系統調用時,會主動把當前 goroutine 的CPU § 轉讓出去,讓其他 goroutine 能被調度並執行,也就是 Golang 從語言層面支持了協程。

Golang 的一大特色就是從語言層面原生支持協程,在函數或者方法前面加 go關鍵字就可創建一個協程。

協程與線程的比較

每個 goroutine (協程) 默認佔用內存遠比 Java 、C 的線程少。
goroutine:2KB(官方)
線程:8MB(參考網絡)= 8192K

線程/goroutine 切換開銷方面:goroutine 遠比線程小!

  • 線程:涉及模式切換(從用戶態切換到內核態)、16個寄存器、PC、SP…等寄存器的刷新等。
  • goroutine:只有三個寄存器的值修改 - PC / SP / DX.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章