工作竊取算法(work-stealing)

工作中,我們經常會用到線程池,通常是任務產生後放到一個任務隊列,線程池中的線程不斷從任務隊列中取任務執行,但這樣設計在一些情況下並不是最優的,更常見的實現是基於work-stealing的線程池。work-stealing從字面理解即工作竊取,工作竊取(work-stealing)算法是指某個線程從其他隊列裏竊取任務來執行。工作竊取的運行流程圖如下:
在這裏插入圖片描述

那麼爲什麼需要使用工作竊取算法呢?假如我們需要做一個比較大的任務,我們可以把這個任務分割爲若干互不依賴的子任務,爲了減少線程間的競爭,於是把這些子任務分別放到不同的隊列裏,併爲每個隊列創建一個單獨的線程來執行隊列裏的任務,線程和隊列一一對應,比如A線程負責處理A隊列裏的任務。但是有的線程會先把自己隊列裏的任務幹完,而其他線程對應的隊列裏還有任務等待處理。幹完活的線程與其等着,不如去幫其他線程幹活,於是它就去其他線程的隊列裏竊取一個任務來執行。而在這時它們會訪問同一個隊列,所以爲了減少竊取任務線程和被竊取任務線程之間的競爭,通常會使用雙端隊列,被竊取任務線程永遠從雙端隊列的頭部拿任務執行,而竊取任務的線程永遠從雙端隊列的尾部拿任務執行。

工作竊取算法的優點是充分利用線程進行並行計算,並減少了線程間的競爭,其缺點是在某些情況下還是存在競爭,比如雙端隊列裏只有一個任務時。並且消耗了更多的系統資源,比如創建多個線程和多個雙端隊列。

即,基於work-strealing的線程池並不是在所有情況下都是最優的,應用它的最佳情景是線程池工作負荷比較重,外部客戶大量提交任務到線程池中。而一般情況下,如果工作負荷不是很重或不是大量短任務這種情況也不一定要用線程池,所以,work-strealing算法還是很實用的。


參考文檔:

一個Work Stealing Pool線程池的實現

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章