2017年9月18日 星期一

Golang sync.WaitGroup 備忘

有時候身上有太多專案不是一件好事
特別是當每個專案用的語言都不一樣時

最近在忙一個專案
使用的語言是 C
故這一陣子比較少用 Golang

等到這個專案要開始寫模擬程式時
又要切回 Golang
一時之間還真的轉不過來

就拿 sync.WaitGroup 來說
這是用來控制 goruntime 正常結束的 struct

不過常常隔一陣子寫 Golang
就會把它當成特殊 type 變數
故會忘記傳指標進去 goruntime
導致程式無法正常結束

於是決定來 trace 一下 source code
好加深印象,以後就不會忘記了

我們先來看 Go/src/sync/waitgroup.go
很明顯的是一個 struct 無誤
 
// A WaitGroup waits for a collection of goroutines to finish.
// The main goroutine calls Add to set the number of
// goroutines to wait for. Then each of the goroutines
// runs and calls Done when finished. At the same time,
// Wait can be used to block until all goroutines have finished.
//
// A WaitGroup must not be copied after first use.
type WaitGroup struct {
 noCopy noCopy

 // 64-bit value: high 32 bits are counter, low 32 bits are waiter count.
 // 64-bit atomic operations require 64-bit alignment, but 32-bit
 // compilers do not ensure it. So we allocate 12 bytes and then use
 // the aligned 8 bytes in them as state.
 state1 [12]byte
 sema   uint32
}

接著再來看它提供的 method Add( )
其宣告形式也是一個指標
 
func (wg *WaitGroup) Add(delta int) {
 statep := wg.state()
 if race.Enabled {
  _ = *statep // trigger nil deref early
  if delta < 0 {
   // Synchronize decrements with Wait.
   race.ReleaseMerge(unsafe.Pointer(wg))
  }
  race.Disable()
  defer race.Enable()
 }
        ...
}

希望以後就不會忘記了

沒有留言:

張貼留言