我有一个关于 Go 例程的问题。
我的代码:
func main() {
ok := make(chan bool, 1)
i := 0
fmt.Println("Starting...")
for i <= 3 {
fmt.Println("Loop: ", i)
go long(ok, i)
time.Sleep(1 * time.Second)
i = i + 1
select {
case _ = <-ok:
default:
fmt.Println("Default")
}
}
fmt.Println("Done...")
}
func long(c chan bool, i int){
fmt.Println("Inside long: ", i)
time.Sleep(3 * time.Second)
fmt.Println("Done with loop: ", i)
c <- true
}
这给了我输出:
Starting...
Loop: 0
Inside long: 0
Default
Loop: 1
Inside long: 1
Default
Loop: 2
Inside long: 2
Done with loop: 0
Loop: 3
Inside long: 3
Done with loop: 1
Done...
因为我在select
中使用了default
,所以 channel 是非阻塞的。主函数退出,所有当前例程也退出。然后我阅读了有关 sync
和 WaitGrops
的内容。
func main() {
ok := make(chan bool, 1)
var wg sync.WaitGroup
i := 0
fmt.Println("Starting...")
for i <= 3 {
fmt.Println("Loop: ", i)
wg.Add(1)
go long(ok, i)
time.Sleep(1 * time.Second)
i = i + 1
select {
case _ = <-ok:
default:
fmt.Println("Default")
}
}
wg.Wait()
fmt.Println("Done...")
}
这给了我:
Starting...
Loop: 0
Inside long: 0
Default
Loop: 1
Inside long: 1
Default
Loop: 2
Inside long: 2
Done with loop: 0
Loop: 3
Inside long: 3
Done with loop: 1
Done with loop: 2
Done with loop: 3
我们现在更接近我想要的执行,即: for 循环使其对函数的所有调用都进行,然后我得到异步结果。如果一切顺利的话那就太好了。但会产生错误:
fatal error: all goroutines are asleep - deadlock!
这是为什么?我应该如何解决它? (是否可以在不知道 wg.Add() 执行多少次的情况下修复?)
最佳答案
您需要在 WaitGroup
上调用 Done()
次数与调用 Add(1)
次数相同,以便 wg .Wait()
可以解除阻塞。您不再需要 channel 来同步:
package main
import (
"sync"
"fmt"
"time"
)
func main() {
var wg sync.WaitGroup
i := 0
fmt.Println("Starting...")
for i <= 3 {
fmt.Println("Loop: ", i)
wg.Add(1)
go long(&wg, i)
time.Sleep(1 * time.Second)
i = i + 1
}
wg.Wait()
fmt.Println("Done...")
}
func long(wg *sync.WaitGroup, i int){
fmt.Println("Inside long: ", i)
time.Sleep(3 * time.Second)
fmt.Println("Done with loop: ", i)
wg.Done()
}
关于go - 等待所有go例程,非阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50052851/