1.5.6 中控制并发执行的Goroutine的最大数目代码示例是否有误
Author: JabinGPCreated Apr 8, 2020Updated Jan 18, 2024
提示: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{}
}Source: chai2010/advanced-go-programming-book