Erlang併發機制 –進程調度

Erlang調度器主要完成對Erlang進程的調度,它是Erlang實現軟件實時和進程之間公平使用CPU的關鍵。Erlang運行時,有4種任務須要被調度:進程,PortLinked-in driver,Erlang虛擬機的系統級活動。html

 

Erlang調度器主要有如下特色:算法

1. 進程調度運行在用戶空間 :Erlang進程不一樣於操做系統進程,Erlang的進程調度也跟操做系統徹底沒有關係,是由Erlang虛擬機來完成的;編程

2. 調度是搶佔式的:每個進程在建立時,都會分配一個固定數目的reduction(R15B中,這個數量默認值是2000),每一次操做(函數調用),reduction就會減小,當這個數量減小到0時或者進程沒有匹配的消息時,搶佔就會發生(無視優先級);ide

3. 每一個進程公平的使用CPU:每一個進程分配相同數量的reduction,能夠保證進程能夠公平的(不是相等的)使用CPU資源函數

4. 調度器保證軟實時性:Erlang中的進程有優先級,調度器能夠保證在下一次調度發生時,高優先級的進程能夠優先獲得執行。性能

 

Reductionspa

受操做系統中基於時間片調度算法的影響,一開始知道有reduction這個概念時,一直想搞清楚這個reduction到底對應多長的絕對時間,不過,從Erlang自己對reduction的使用來看,徹底沒有必要糾結這個問題。《Erlang編程指南》一書中對reduction的說明以下:操作系統

程序中的每個命令,不管它是一個函數調用,仍是一個算術操做,或者內置線程

函數,都會分配必定數量的reduction。虛擬機使用這個值來衡量一個進程的活orm

動水平。

看到這個定義的第一反應是,若是一個函數調用的執行時間很長怎麼辦?那不是一個進程會長時間的佔用資源?Erlang對這個問題的答案是Trap機制,上一篇中有提到過,它的其中一個功能就是把費時的操做分階段作,好比lists:reverser和lists:member可能會根據輸入的不一樣會有很大的變化,因此就會使用到Trap機制:先執行一段時間,再Trap,而後再次調度到的時候再繼續執行。

 

SMP支持

從R11B(2006)Erlang開始支持SMP(Symmetrical Multi Processor,也就是多核)。Erlang對SMP的支持分爲如下幾個階段:

1). 單調度器、單運行隊列:調度器運行在虛擬機主進程中的一個線程中,從單個任務隊列中獲取運行進程,由於只有一個線程,因此對運行隊列的訪問不須要鎖;

2). 多調度器、單運行隊列:調度器的個數能夠自定義(參見erl命令的+S參數,默認數量同CPU核的數量),每一個調度器運行在一個線程中,可是隻有一個運行隊列,全部調度器都從同一個運行隊列獲取運行進程,因此會涉及到共享資源的訪問,須要用到鎖。

3). 多調度器、多運行隊列:每一個調度器都綁定有一個運行隊列,每一個調度器都從各自的運行隊列中獲取運行進程。相比單運行隊列,多運行隊列會減小鎖衝突,提升性能,可是,由於涉及到多運行隊列,就必須要考慮負載問題:若是一個調度器很忙,另外一個很閒,那怎麼辦?Erlang虛擬機存在一個任務遷移的邏輯,來保證各個調度器達到平衡。

 

進程優先級

Erlang進程有四種優先級:max, high, normal, low(max只在Erlang運行時系統內部使用,普通進程不能使用)。Erlang運行時有兩個運行隊列對應着max和high優先級的運行任務,normal和low在同一個隊列中。

調度器在調度發生時,老是首先查看具體max優先級的進程隊列,若是隊列中有能夠進行的進程,就會運行,直到這個隊列爲空。而後會對high優先級的進程隊列作一樣的操做(在SMP環境,由於同時有幾個調度器,因此在同一時間,可能會有不一樣優先級的任務在同時運行;但在同一個調度器中,同一時間,確定是高優先級的任務優先運行)。

普通進程在建立時,通常是normal優先級。normal和low優先級的進程只有在系統中沒有max和high優先級的進程可運行時纔會被調度到。一般狀況下,normal和low優先級的進程交替執行,low優先級得到CPU資源相對更少(通常狀況下):low優先級的任務只有在運行了normal優先級任務特定次數後(在R15B中,這個數字是8)纔會被調度到(也就是說只有在調度了8個normal優先級的進程後,low優先級的進程纔會被調度到,即便low優先級的進程比normal優先級的進程更早進入調度隊列,這種機制可能會引發優先級反轉:假如你有成千上萬的活動normal進程,而只有幾個low優先級進程,那麼相比normal進程,low優先級可能會得到更多的CPU資源)。

 

調度算法的實現見[$OTP_SRC/erts/emulator/beam/erl_process.c --> schedule],下面的圖片是算法流程圖,來源於這篇論文:Characterizing the Scalability of Erlang VM on Many-core Processors

相關文章
相關標籤/搜索