示例用法sync.WaitGroup是否正确?它给出了预期的结果,但我不确定wg.Add(4)和 的位置wg.Done()。一次加四个 goroutine 有意义wg.Add()吗?7 j; C2 g% t) S: G5 C
http://play.golang.org/p/ecvYHiie0P- V' Q; Q- S* E& d% v
package mainimport "fmt" "sync" "time")func dosomething(millisecs time.Duration,wg *sync.WaitGroup) duration := millisecs * time.Millisecond time.Sleep(duration) fmt.Println("Function in background,duration:",duration) wg.Done()}func main() var wg sync.WaitGroup wg.Add(4) go dosomething(200,&wg) go dosomething(400,&wg) go dosomething(150,&wg) go dosomething(600,&wg) wg.Wait() fmt.Println("Done")}/ P( M" l" B& i$ Y9 g( P# K- ?
结果(如预期):3 T d3 x6 p7 A# _
Function in background,duration: 150msFunction in background,duration: 200msFunction in background,duration: 400msFunction in background,duration: 600msDone& L* A8 S6 G7 o# ]- z; H! m# S
func main() var wg sync.WaitGroup wg.Add(1) go dosomething(200,&wg) wg.Add(1) go dosomething(400,&wg) wg.Add(1) go dosomething(150,&wg) wg.Add(1) go dosomething(600,&wg) wg.Wait() fmt.Println("Done")} 4 w$ B, y/ g: c% G7 \
然而,wg.Add当你知道它会被调用多少次时,一遍又一遍地调用是没有意义的。1 _ j5 u" E% x {# X" n
Waitgroups如果计数器低于零,恐慌。计数器从零开始,每个Done()都是 a-1并且每个都Add()取决于参数。因此,为了确保计数器不低于并避免恐慌,有必要Add()进行担保来之前Done()。) q; ^) }7 ~/ Q9 O* g; e: B
在 Go 这种保证由内存模型提供。/ ~: C1 n: I8 K2 M6 z" ]2 R
内存模型指出,单个 goroutine 中的所有句子似乎都按照与编写相同的顺序执行。它们实际上可能不会按这个顺序排列,但结果就像它一样。goroutine 在go只有在调用它的句子后才。theAdd()出现在go在句子之前go 出现了句子the 之前Done(),我们知道 theAdd()出现在 the 之前Done()。' |) C+ ]" i+ E: u6 \, g p
如果您将go把句子放在前面Add()程序可能正确运行。但是,由于不能保证,这将是一个竞争条件。