package main
import (
"fmt"
"runtime"
"sync"
)
func init() {
fmt.Println("Current Go Version:", runtime.Version())
}
func main() {
runtime.GOMAXPROCS(1)
count := 10
wg := sync.WaitGroup{}
wg.Add(count * 2)
for i := 0; i < count; i++ {
go func() {
fmt.Printf("[%d]", i)
wg.Done()
}()
}
for i := 0; i < count; i++ {
go func(i int) {
fmt.Printf("-%d-", i)
wg.Done()
}(i)
}
wg.Wait()
}
有疑问加站长微信联系(非本文作者)

这里是答案 https://wide.b3log.org/playground/0bc5162cf88188d75a2e59ef537085d0.go
这是很经典的问题
闭包 for 取 i
是的,很精典,但是今天发现答案是 -9-[10][10][10][10][10][10][10][10][10][10]-0--1--2--3--4--5--6--7--8- 不知道为会第二个循环会先执行一次后,再执行第一个循环,而且每次答案都 一样
-9-[10][10][10][10][10][10][10][10][10][10]-0--1--2--3--4--5--6--7--8- 不知道为会第二个循环会先执行一次后,再执行第一个循环,而且每次答案都 一样
请勿依赖调度。具体调度算法,每个版本可能都不一样。
谁能讲一下这是什么情况么?不太懂。
没必要深究这些,依照规范里面明确说明的方式来同步准没错
这个你要去看 golang 的调度算法了,具体是什么也不是一句话就可以说清楚的
好的,谢谢
好的,谢谢
猜想代码想要说明两个问题:
一是匿名函数中的循环变量快照问题:第一个for循环问题(一般情况下这么认为这段代码是有问题的)的原因在于循环变量的作用域,for循环语句引入了新的词法块,循环变量
i
在这个词法块中被声明。在该循环中生成的所有函数值都共享相同的循环变量。需要注意,函数值中记录的是循环变量的内存地址,而不是循环变量某一时刻的值,后续的迭代会不断更新i
的值,当函数执行时,for循环已完成,i
中存储的值等于最后一次迭代的值。为了解决这个问题,我们会引入一个局部变量,作为循环变量的副本,如图:二是, GOMAXPROCS设置为1,是设置一个cpu核心去处理,将影响goroutine的并发,代码中的go func()相当于串行执行(不是并行),所有输出结果始终是一样
关键在于第一个9。
Go 有一套自己的管理、调度、执行goroutine的方式就是我们说的Go的并发, 所以我们可以假装这样理解(代码中第二个for循环中的goroutine刚执行一次,就被暂停执行其他的goroutine了),这是Go控制管理的