1.5.6 中控制并发执行的Goroutine的最大数目代码示例是否有误
JabinGP opened this issue · 2 comments
JabinGP commented
提示:1.5.6 基于Channel的通信 中控制并发执行的Goroutine的最大数目代码示例
书中原文
我们可以根据控制Channel的缓存大小来控制并发执行的Goroutine的最大数目, 例如:
var limit = make(chan int, 3)
func main() {
for _, w := range work {
go func() {
limit <- 1
w()
<-limit
}()
}
select{}
}
疑惑
代码中没有给出work变量的定义,我个人猜测为函数数组,如下
var work = []func(){
func() { log.Println("1"); time.Sleep(1 * time.Second) },
func() { log.Println("2"); time.Sleep(1 * time.Second) },
func() { log.Println("3"); time.Sleep(1 * time.Second) },
func() { log.Println("4"); time.Sleep(1 * time.Second) },
func() { log.Println("5"); time.Sleep(1 * time.Second) },
func() { log.Println("6"); time.Sleep(1 * time.Second) },
func() { log.Println("7"); time.Sleep(1 * time.Second) },
func() { log.Println("8"); time.Sleep(1 * time.Second) },
}
如果work为函数数组,Goroutine在main中的创建并不是同步的,匿名函数中是否应该需要考虑w为闭包引用变量的问题?如定义一个同名局部变量覆盖w来复制一份w的值。
var limit = make(chan int, 3)
var work = []func(){
func() { log.Println("1"); time.Sleep(1 * time.Second) },
func() { log.Println("2"); time.Sleep(1 * time.Second) },
func() { log.Println("3"); time.Sleep(1 * time.Second) },
func() { log.Println("4"); time.Sleep(1 * time.Second) },
func() { log.Println("5"); time.Sleep(1 * time.Second) },
func() { log.Println("6"); time.Sleep(1 * time.Second) },
func() { log.Println("7"); time.Sleep(1 * time.Second) },
func() { log.Println("8"); time.Sleep(1 * time.Second) },
}
func main() {
for _, w := range work {
w := w
go func() {
limit <- 1
w()
<-limit
}()
}
select{}
}
chai2010 commented
你已经不需要看书了,欢迎提交PR
nm2006717 commented
关于这段示例我有个疑问:
在for循环中不是一下开启len(work)个协程吗?只是因为limit的限制,只能保证同时只能有3个协程执行任务,其余协程阻塞吗?