Go WaitGroup原始碼決議
結構體
type WaitGroup struct {
noCopy noCopy
state1 [3]uint32
}
其中state1代表三個欄位:counter, waiter, sema
- counter:計數器,每次經過wg.Add(X)或者wg.Done()后的值
- waiter:呼叫wg.Wait()的數量,也就是等待者的數量
- sema:信號量,用于換醒Wait()函式
退出WaitGroup的條件
counter == 0
Add(n)
- 更新counter的值,
counter += n - 判斷當前
counter > 0 || waiter == 0,滿足條件,說明當前還有groutine沒有執行完,直接回傳, - 走到這一步,說明
counter == 0 && waiter != 0,說明groutine全部執行了Done()方法,換醒執行了wg.Wait()的協程,將state設定成0,回傳,
Wait()
- 回圈判斷下面操作
- 判斷
counter == 0,如果為true,說明groutine已經全部執行了Done()方法,Wait Done, - 此時
counter != 0,說明需要阻塞當前協程的執行,執行下面的CAS判斷 - CAS判斷wg.state有沒有被改變,沒有則更新wg.state為1,當前協程進入sleep狀態,等待信號量換醒,換醒后繼續回圈判斷,此時counter==0,直接wait done,
- CAS判斷wg.state有沒有被改變,有則繼續回圈判斷,繼續判斷counter
Done()
Done 的實作就是 Add. 只不過我們常規用法 wg.Add(1) 是加 1 ,wg.Done() 是減 1,即 wg.Done() 可以用 wg.Add(-1) 來代替,盡管我們知道 wg.Add 可以傳遞負數當 wg.Done 使用,但是還是別這么用,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/458100.html
標籤:Go
