Golang:線程 和 協程 的區別

做者:林冠宏 / 指尖下的幽靈git

掘金:juejin.im/user/587f0d…github

博客:www.cnblogs.com/linguanh/編程

GitHub : github.com/af913337456…多線程

騰訊雲專欄: cloud.tencent.com/developer/u…併發


目錄

  • 前言
  • 協程
  • 協程的特色
    • 第 1第 2
    • 特色中的第 3 和 第 4 點
  • 和線程的總體對比

前言

國慶愉快各位,距離上次發文快兩個月了,19年也快結束了。如今的總結更可能是放在了草稿 而沒有發出,此次詳細分享下在 Go 中,線程和協程的區別及其關係編程語言

協程

協程,英文名Coroutine。但在 Go 語言中,協程的英文名是:gorutine。它經常被用於進行多任務,即併發做業。沒錯,就是多線程做業的那個做業。函數

雖然在 Go 中,咱們不用直接編寫線程之類的代碼來進行併發,可是 Go 的協程卻依賴於線程來進行。post

下面咱們來看看它們的區別。性能

線程的基礎介紹,這裏請自行網上搜索文章,由於關於線程的優秀介紹文章已經不少。區塊鏈

協程的特色

這裏先直接列出線程的特色,而後從例子中進行解析。

  1. 多個協程可由一個或多個線程管理,協程的調度發生在其所在的線程中。
  2. 能夠被調度,調度策略由應用層代碼定義,便可被高度自定義實現。
  3. 執行效率高。
  4. 佔用內存少。

上面第 1第 2

咱們來看一個例子:

func TestGorutine(t *testing.T) {
	runtime.GOMAXPROCS(1)  // 指定最大 P 爲 1,從而管理協程最多的線程爲 1 個
	wg := sync.WaitGroup{} // 控制等待全部協程都執行完再退出程序
	wg.Add(2)
	// 運行一個協程
	go func() {
		fmt.Println(1)
		fmt.Println(2)
		fmt.Println(3)
		wg.Done()
	}()

	// 運行第二個協程
	go func() {
		fmt.Println(65)
		fmt.Println(66)
		// 設置個睡眠,讓該協程執行超時而被掛起,引發超時調度
		time.Sleep(time.Second)
		fmt.Println(67)
		wg.Done()
	}()
	wg.Wait()
}
複製代碼

上面的代碼片斷跑了兩個協程,運行後,觀察輸出的順序是交錯的。多是:

65
66
1
2
3
67
複製代碼

意味着在執行協程A的過程當中,能夠隨時中斷,去執協程行B,協程B也可能在執行過程當中中斷再去執行協程A。

看起來協程A 和 協程B 的運行像是線程的切換,可是請注意,這裏的 A 和 B 都運行在同一個線程裏面。它們的調度不是線程的切換,而是純應用態的協程調度

關於上述代碼中,爲何要指定下面兩行代碼?

runtime.GOMAXPROCS(1)
time.Sleep(time.Second)
複製代碼

這須要您去看下 Go 的協程調度入門基礎,請看我以前的另一篇調度分析文章:

Go 的協程調度機制

若是不設置 runtime.GOMAXPROCS(1),那麼程序將會根據操做系統的 CPU 核數而啓動對應數量的 P,致使多個 M,即線程的啓動。那麼咱們程序中的協程,就會被分配到不一樣的線程裏面去了。爲了演示,故設置數量 1,使得它們都被分配到了同一個線程裏面,存於線程的協程隊列裏面,等待被執行或調度。

協程特色中的第 3 和 第 4 點。

  1. 執行效率高。
  2. 佔用內存少。

由於協程的調度切換不是線程切換,而是由程序自身控制,所以,沒有線程切換的開銷,和多線程比,線程數量越多,協程的性能優點就越明顯。調度發生在應用態而非內核態。

內存的花銷,使用其所在的線程的內存,意味着線程的內存能夠供多個協程使用。

其次協程的調度不須要多線程的鎖機制,由於只有一個線程,也不存在同時寫變量衝突,因此執行效率比多線程高不少。

和線程的總體對比

比較的點 線程 協程
數據存儲 內核態的內存空間 通常是線程提供的用戶態內存空間
切換操做 操做最終在內核層完成,應用層須要調用內核層提供的 syscall 底層函數 應用層使用代碼進行簡單的現場保存和恢復便可
任務調度 由內核實現,搶佔方式,依賴各類鎖 由用戶態的實現的具體調度器進行。例如 go 協程的調度器
語音支持程度 絕大部分編程語言 部分語言:Lua,Go,Python ...
實現規範 按照現代操做系統規範實現 無統一規範。在應用層由開發者實現,高度自定義,好比只支持單線程的線程。不一樣的調度策略,等等

我的廣告

本人技術書籍《區塊鏈以太坊DApp開發實戰》現已出版並可網購了,適合初中級區塊鏈技術相關研發人員閱讀。

相關文章
相關標籤/搜索