sync.WaitGroup示例正确吗? [英] Example for sync.WaitGroup correct?
问题描述
wg.Add(4)
和 wg.Done()$ c的位置$ C>。使用
wg.Add()
?一次性添加四个goroutines是否有意义?
http://play.golang.org/p/ecvYHiie0P
package main
pre>
import(
fmt
sync
time
)
func dosomething(millisecs time.Duration,wg * sync.WaitGroup){
duration:= millisecs * time.Millisecond
time.Sleep(duration)
fmt.Println(Function在后台,持续时间:,持续时间)
wg.Done()
}
func main(){
var wg sync.WaitGroup
wg添加(4)
去dosomething(200,& wg)
去dosomething(400,& wg)
去dosomething(150,& wg)
去dosomething (600,& wg)
wg.Wait()
fmt.Println(完成)
}
结果(如预期):
持续时间:150ms
在后台运行,持续时间:2 00ms
后台功能,持续时间:400ms
后台功能,持续时间:600ms
完成
解决方案是的,这个例子是正确的。
wg.Add()
在转到
语句之前发生以防止竞争条件是很重要的。以下内容也是正确的:func main(){
var wg sync.WaitGroup
wg .Add(1)
go dosomething(200,& wg)
wg.Add(1)
go dosomething(400,& wg)
wg.Add(1 )
去dosomething(150,& wg)
wg.Add(1)
去dosomething(600,& wg)
wg.Wait()
fmt.Println(完成)
}
然而,它是当你已经知道它会被调用多少次时,反复地再次调用
wg.Add
。
等待组
恐慌,如果计数器低于零。计数器从零开始,每个Done()
是一个-1
并且每个Add( )
取决于参数。因此,您需要Add()
保证在Done()
避免恐慌。
在Go中,这样的保证是由内存模型
内存模型指出,单个goroutine中的所有语句似乎都按照写入的顺序执行。他们可能不会按照这个顺序,但结果就好像是这样。这还保证,直到
转到
语句之后, goroutine才会运行称之为。由于Add()
发生在go
语句之前,而go
语句出现在Done()
之前,我们知道Add()
出现在完成()
。
如果你有
go
Add()
,程序可能正常运行。但是,这将是一个竞争条件,因为它不会得到保证。Is this example usage of
sync.WaitGroup
correct? It gives the expected result, but I am unsure about thewg.Add(4)
and the position ofwg.Done()
. Does it make sense to add the four goroutines at once withwg.Add()
?http://play.golang.org/p/ecvYHiie0P
package main import ( "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") }
Result (as expected):
Function in background, duration: 150ms Function in background, duration: 200ms Function in background, duration: 400ms Function in background, duration: 600ms Done
解决方案Yes, this example is correct. It is important that the
wg.Add()
happens before thego
statement to prevent race conditions. The following would also be correct: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") }
However, it is rather pointless to call
wg.Add
over and over again when you already know how many times it will be called.
Waitgroups
panic if the counter falls below zero. The counter starts at zero, eachDone()
is a-1
and eachAdd()
depends on the parameter. So, you need theAdd()
to be guaranteed to come before theDone()
to avoid panics.In Go, such guarantees are given by the memory model.
The memory model states that all statements in a single goroutine appear to be executed in the same order as they are written. It is possible that they won't actually be in that order, but the outcome will be as if it was. It is also guaranteed that a goroutine doesn't run until after the
go
statement that calls it. Since theAdd()
occurs before thego
statement and thego
statement occurs before theDone()
, we know theAdd()
occurs before theDone()
.If you were have the
go
statement come before theAdd()
, the program may operate correctly. However, it would be a race condition because it would not be guaranteed.这篇关于sync.WaitGroup示例正确吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!