Goroutine 調度模型猜想

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

前言

近日在學習go語言,go語言的一個重大特色就是支援協程(coroutine),即使用者級線程。由運行在使用者態程式實現“執行體”的調度和切換(本文將一個可並發執行的邏輯單元稱為“執行體”),整個過程運行在一個或多個線程上,執行體切換過程不用“陷入”核心態,因此較為輕量。

這種方式也有一定的缺點,因為協程概念提出的很早,主流語言卻沒有提供支援,必有原因,這個我們以後討論。

當然,為了更好的瞭解goroutine,我們就有必要談談goroutine調度模型的實現。不過,作者是java開發人員,對分析c及彙編源碼之類的事情能力有限,雖然有很多參考資料及公開的源碼,分析來分析去,我也是醉了。所以在看了一些goroutine scheduler資料後,本文從另一個角度切入,描述下一個簡單的協程調度模型如何?。最後的分析可能與goroutine實際的實現不太一致,還望大家見諒。

單線程上的協程調度模型

假設只有一個線程,該線程運行一個發送器,發送器從其管理的執行體集合中取出一個執行體交給線程執行。該線程執行邏輯如下:

如果考慮執行體各種非正常退出的情況:

由此我們可以確定,實現該線程邏輯需要兩個抽象:執行體和發送器。

  • 執行體包含:執行體的上下文環境,執行邏輯等
  • 發送器:執行體集合(鏈表),執行體切換等

該模型有兩個問題:

  • 除非執行體執行完畢、主動放棄或調用系統調用,執行體將一直“佔用”線程。調度器因為沒有“佔用”線程,也只能幹看著。這種非搶佔式方式是協程調度模型的通病。
  • 執行體執行過程中可能向執行體集合添加新的執行體,導致該線程負擔過大。

多個線程上協程調度模型

可以想見,如果只是運行在一個線程上,那麼goroutine也太簡單了,接下來談談運行在多個線程上的情況。

不管是運行在幾個線程上,線程總得一個一個啟動,是第一個線程的運行邏輯。當然,在第一個線程啟動前,肯定要為整個調度模型做一些資料結構的初始化工作。

多個線程上調度跟單個線程調度有一個很大的不同就是:一旦執行體鏈表包含的執行體過多,就需要開啟新的線程,轉移部分執行體。反之,如果某個線程執行體鏈表為空白,則需要從全域鏈表或其它線程那裡“挖”執行體。

執行體本身是有狀態的。

  • 主動放棄執行。將執行體設定為runnable狀態,然後放入到全域執行體集合。(看來執行體主動放棄執行,不僅是放棄所線上程的執行機會,還不想在本線程繼續呆了)
  • channel操作和網路操作等。執行體被置為wating狀態,從本線程執行體集合中剝離,直到其依賴的條件滿足。
  • 調用系統調用。

第一個線程開始執行後,go調度模型還會建立一個sysmon線程(負責監控,不運行執行體)還有一個問題,那就是一旦執行體中調用系統調用,整個線程會被阻塞。為了不影響線程中其它執行體的執行,Go語言完全是自己封裝的系統調用,所以在封裝系統調用的時候,可以做不少手腳,也就是進入系統調用的時候執行entersyscall,退出後又執行exitsyscall函數。entersyscall將執行體從當前執行體鏈表中剝離,並將改變P的狀態為syscall。Sysmon監控線程會掃描所有的P,發現一個P處於了syscall的狀態,就知道這個P遇到了執行體在做系統調用,於是系統監控線程就會建立一個新的線程去把這個處於syscall的P給搶過來,開始幹活,這樣這個小車中的其它執行體就可以繞過之前系統調用的等待了。被搶走P的線程等系統調用返回後,發現自己的P沒了,不能繼續幹活了,於是只能把執行系統調用的執行體放回到全域鏈表中,自己睡覺去了。

goroutine調度模型的四個抽象

有了上述鋪墊,我們再來看goroutine調度模型4個重要結構,分別是M、G、P、Sched,前三個定義在runtime.h中,Sched定義在proc.c中。

  • Sched結構就是調度器,它維護有儲存M和G的隊列(可能是全域的)以及調度器的一些狀態資訊等。
  • M代表核心級線程,一個M就是一個線程,goroutine就是跑在M之上的;M是一個很大的結構,裡面維護小對象記憶體cache(mcache)、當前執行的goroutine、隨機數發生器等等非常多的資訊。
  • P全稱是Processor,處理器,它的主要用途就是用來執行goroutine的,所以它也維護了一個goroutine隊列,裡面儲存了所有需要它來執行的goroutine。
  • G就是goroutine實現的核心結構了,G維護了goroutine需要的棧、程式計數器以及它所在的M等資訊。

這樣從前到後談下來,是不是更順一些。

參考文獻

goroutine與調度器

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.