让\xe2\x80\x99s 说我使用 aWaitGroup让应用程序的主线程等待,直到我从所述 main 启动的所有 goroutine 完成。
是否有一种安全、直接的方法可以在任何时间点评估有多少与 said 相关的 goroutineWaitGroup仍在运行?
我正在尝试了解 golang频道和同步。当我运行我的程序与竞争检测器,它导致了比赛的检测。
func main() {
ch := make(chan int)
done := make(chan struct{})
wg := sync.WaitGroup{}
go func() {
defer close(ch)
defer close(done)
wg.Wait()
done <- struct{}{}
}()
for i := 0; i < 5; i++ {
x := i
wg.Add(1)
go func() {
defer wg.Done()
fmt.Println("Value: ", x)
ch <- x
}()
}
loop:
for {
select {
case i := <-ch:
fmt.Println("Value: ", i)
case <- done:
break loop
}
} …Run Code Online (Sandbox Code Playgroud) 我有以下代码作为测试的一部分:
expected := 10
var wg sync.WaitGroup
for i := 0; i < expected; i++ {
go func(wg *sync.WaitGroup) {
wg.Add(1)
defer wg.Done()
// do something
}(&wg)
}
wg.Wait()
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,我panic: Fail in goroutine after TestReadWrite has completed在运行“go test”时得到了。当使用“go test -race”运行时,我没有感到恐慌,但测试后来失败了。在这两种情况下,尽管有 wg.Wait(),但 goroutine 并未完成执行。
我做了以下更改,现在测试按预期工作:
expected := 10
var wg sync.WaitGroup
wg.Add(expected)
for i := 0; i < expected; i++ {
go func(wg *sync.WaitGroup) {
defer wg.Done()
// do something
}(&wg)
}
wg.Wait()
Run Code Online (Sandbox Code Playgroud)
我的疑问是:
wg.Add(1)在 goroutine 内部完成的。为什么在这种特定情况下它会表现出意外?这里发生的情况似乎是,一些 …我有一个可以在单独的 goroutine 中顺序或同时调用的函数。
我想确保该函数在主 goroutine 完成之前完全执行,因此我将 *sync.WaitGroup 参数传递给该函数。现在,在某些地方该函数将被顺序调用。
我可以将 nil waitGroup 传递给函数,如下所示:
func my_func(wg *sync.WaitGroup){
if wg != nil{
defer wg.Done()
}
// do the task
}
func main(){
my_func(nil) // sequential call
wg := sync.WaitGroup{}
wg.Add(1)
go my_func(&wg) // concurrent call
wg.Wait()
}
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法来实现这一目标?
谁能告诉我为什么会出现恐慌。这个demo的背景是验证切片并发写入的行为,但是当我运行demo时,偶尔会出现panic(并非总是如此)。所以为什么?
代码:
func main() {
for i := 0; i < 10000; i++ {
// when capacity > 2, panic disappear
b := make([]int, 2, 2)
b[0], b[1] = 0, 1
wg := sync.WaitGroup{}
wg.Add(1)
go func() {
b = append(b, 3)
wg.Done()
}()
wg.Add(1)
go func() {
b = append(b, 4)
wg.Done()
}()
wg.Wait()
}
}
Run Code Online (Sandbox Code Playgroud)
错误:
panic: sync: negative WaitGroup counter
goroutine 12821 [running]:
sync.(*WaitGroup).Add(0x0?, 0xc0000f4ba0?)
/usr/local/go/src/sync/waitgroup.go:83 +0xda
sync.(*WaitGroup).Done(...)
/usr/local/go/src/sync/waitgroup.go:108
main.main.func1()
/Users/liushi/Projects/go/golang-demo/main.go:54 +0x97
created by main.main
/Users/liushi/Projects/go/golang-demo/main.go:48 +0x11f …Run Code Online (Sandbox Code Playgroud)