回答

收藏

sync.WaitGroup 的示例是否正确?

技术问答 技术问答 231 人阅读 | 0 人回复 | 2023-09-12

示例用法sync.WaitGroup是否正确?它给出了预期的结果,但我不确定wg.Add(4)和 的位置wg.Done()。一次加四个 goroutine 有意义wg.Add()吗?
5 j( g4 G: D1 u* p( Xhttp://play.golang.org/p/ecvYHiie0P$ t6 a0 p) A. E. e0 T# |3 t
    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")}
    8 _8 z. ~9 ]  e4 P9 R1 {% X
结果(如预期):
, K' o  q* c; \9 V4 l5 Q0 S2 A. f0 n
    Function in background,duration: 150msFunction in background,duration: 200msFunction in background,duration: 400msFunction in background,duration: 600msDone, C# v4 }9 S) v2 ?/ l4 N
               & h' Q# j+ ?0 N; J
    解决方案:                                                               
# S9 K+ d' T, W5 e$ R                                                                是的,这个例子是正确的。句子很重要wg.Add()以前发生过go防止竞争条件。以下也是正确的:) O9 S0 Y8 E- A6 ?  \9 P. O3 O/ E) @
    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")}
    8 ^; a7 W) n* R9 F3 f
然而,wg.Add当你知道它会被调用多少次时,一遍又一遍地调用是没有意义的。
+ z+ g5 k: I5 j* E7 IWaitgroups如果计数器低于零,恐慌。计数器从零开始,每个Done()都是 a-1并且每个都Add()取决于参数。因此,为了确保计数器不低于并避免恐慌,有必要Add()进行担保来之前Done()。
. ~% x# p+ f6 K0 i3 v! [在 Go 这种保证由内存模型提供。
9 b( A* j5 W7 `$ I/ K* K内存模型指出,单个 goroutine 中的所有句子似乎都按照与编写相同的顺序执行。它们实际上可能不会按这个顺序排列,但结果就像它一样。goroutine 在go只有在调用它的句子后才。theAdd()出现在go在句子之前go 出现了句子the 之前Done(),我们知道 theAdd()出现在 the 之前Done()。
4 e' h5 q! x/ N% G$ g) j/ {如果您将go把句子放在前面Add()程序可能正确运行。但是,由于不能保证,这将是一个竞争条件。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则