From fad2e7d766457db25185cebde5569d994fc6492e Mon Sep 17 00:00:00 2001 From: JabinGP <1748511181@qq.com> Date: Thu, 9 Apr 2020 20:21:03 +0800 Subject: [PATCH] fix: ch1-05 1.5.6 --- ch1-basic/ch1-05-mem.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/ch1-basic/ch1-05-mem.md b/ch1-basic/ch1-05-mem.md index a59246c..437d2c5 100644 --- a/ch1-basic/ch1-05-mem.md +++ b/ch1-basic/ch1-05-mem.md @@ -355,20 +355,29 @@ func main() { ```go var limit = make(chan int, 3) +var work = []func(){ + func() { println("1"); time.Sleep(1 * time.Second) }, + func() { println("2"); time.Sleep(1 * time.Second) }, + func() { println("3"); time.Sleep(1 * time.Second) }, + func() { println("4"); time.Sleep(1 * time.Second) }, + func() { println("5"); time.Sleep(1 * time.Second) }, +} func main() { for _, w := range work { - go func() { + go func(w func()) { limit <- 1 w() <-limit - }() + }(w) } select{} } ``` -最后一句`select{}`是一个空的管道选择语句,该语句会导致`main`线程阻塞,从而避免程序过早退出。还有`for{}`、`<-make(chan int)`等诸多方法可以达到类似的效果。因为`main`线程被阻塞了,如果需要程序正常退出的话可以通过调用`os.Exit(0)`实现。 +在循环创建`Goroutine`过程中,使用了匿名函数并在函数中引用了循环变量`w`,由于`w`是引用传递的而非值传递,因此无法保证`Goroutine`在运行时调用的`w`与循环创建时的`w`是同一个值,为了解决这个问题,我们可以利用函数传参的值复制来为每个`Goroutine`单独复制一份`w`。 + +循环创建结束后,在`main`函数中最后一句`select{}`是一个空的管道选择语句,该语句会导致`main`线程阻塞,从而避免程序过早退出。还有`for{}`、`<-make(chan int)`等诸多方法可以达到类似的效果。因为`main`线程被阻塞了,如果需要程序正常退出的话可以通过调用`os.Exit(0)`实现。 ## 1.5.7 不靠谱的同步