本文主要是介绍用syc.WaitGroup来等待go协程执行完毕, 顺便看看协程并发数的控制方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
看程序:
package mainimport ("fmt""time"
)func print(i int) {time.Sleep(1e9)fmt.Println(i)
}func main() {for i := 0; i < 10; i++ {go func(n int) {print(n)}(i)}
}
结果没有任何输出,因为主协程很快退出了。
等待一下,变为:
package mainimport ("fmt""time"
)func print(i int) {time.Sleep(1e9)fmt.Println(i)
}func main() {for i := 0; i < 10; i++ {go func(n int) {print(n)}(i)}for {}
}
结果:
7
9
3
4
5
8
0
6
1
2
这种等待太傻了, 改为:
package mainimport ("fmt""sync""time"
)func print(i int) {time.Sleep(1e9)fmt.Println(i)
}func main() {var wg sync.WaitGroupfor i := 0; i < 10; i++ {wg.Add(1)go func(n int) {defer wg.Add(-1) // same: defer wg.Done()print(n)}(i)}wg.Wait()
}
结果:
8
1
5
0
9
4
7
2
6
3
分析一下wg.Wait执行等待操作, 直到wg的计数变为0才返回。 在上面例子中,Add(1)了10次, 然后Add(-1)了10次,刚好。 我们把程序变一下:
package mainimport ("fmt""sync""time"
)func print(i int) {time.Sleep(1e9)fmt.Println(i)
}func main() {var wg sync.WaitGroupwg.Add(11)for i := 0; i < 10; i++ {go func(n int) {defer wg.Add(-1) // same: defer wg.Done()print(n)}(i)}wg.Wait()
}
可以看到,计数达到11次,但只有10次的add(-1), 显然wg.Wait永远无法退出,提示:fatal error: all goroutines are asleep - deadlock!
再看:
package mainimport ("fmt""sync""time"
)func print(i int) {time.Sleep(1e9)fmt.Println(i)
}func main() {var wg sync.WaitGroupwg.Add(5)for i := 0; i < 10; i++ {go func(n int) {defer wg.Add(-1) // same: defer wg.Done()print(n)}(i)}wg.Wait()
}
结果出错,提示信息:
panic: sync: WaitGroup is reused before previous Wait has returned
panic: sync: negative WaitGroup counter
看到没, negative counter了。
最后,来看看协程并发数目的控制。 假设有102个离线任务需要并发执行,难道要开102个协程吗? 来看看怎么控制:
package mainimport ("fmt""sync""time"
)func print(i int) {time.Sleep(1e9)
}func main() {var wg sync.WaitGroupbegin := time.Now().Unix()j := 0for i := 0; i < 102; i++ {wg.Add(1)go func(n int) {defer wg.Add(-1) print(n)}(i)j++if j == 10 {wg.Wait()j = 0}}wg.Wait() end := time.Now().Unix()fmt.Println(end - begin)
}
分析下结果, 不难得知, 结果为11. 运行了一下, OK.
另外,要注意,即使写连续写多个wg.Wait,也没有问题。
不多说。
这篇关于用syc.WaitGroup来等待go协程执行完毕, 顺便看看协程并发数的控制方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!