
package main import ( "runtime" "sync" ) func main() { runtime.GOMAXPROCS(1) var wg sync.WaitGroup wg.Add(20) for i := 0; i < 10; i++ { go func(i int) { println(i) wg.Done() }(i) } for i := 10; i < 20; i++ { go func(i int) { println(i) wg.Done() }(i) } wg.Wait() } https://play.golang.org/p/nrEveScSaeI
问题: 执行结果为什么会先打印出 19 再顺序输出?请各位大佬不吝赐教
我记得之前有看过 M P G 模型中 GOMAXPROCS 可以控制 P 的数量
1 reus 2019-04-17 16:26:22 +08:00 偶然而已,按什么顺序都是对的,goroutine 的执行顺序是不确定的 |
3 keepeye 2019-04-17 16:30:14 +08:00 不专业的回答:最后一个 goroutine 会被放在一个"即将被执行的"地方,优先级最高。 话说,goroutine 不需要关心顺序吧 |
4 mscb 2019-04-17 16:31:45 +08:00 via Android 没仔细了解过细节。设置 gomaxprocs 后,应该只是控制 p 的数量,没有控制 m 的数量吧? m 不变的话底层还是会有多个线程,一个 g 阻塞了,其他 m 会来偷 g 过去运行。不知道我理解的对不对。欢以上仅供参考,欢迎各位大佬赐教,确实没仔细了解过调度这一块 |
5 punyGod 2019-04-17 16:33:18 +08:00 它会把最新的一个放到本地的 queue 中。这样它就会被优先执行 |
6 mscb 2019-04-17 16:35:56 +08:00 via Android 另外就算是单线程的协程也不能保证能顺序执行哇。主要看添加到队列里的形态,以及调度的情况 |
10 reus 2019-04-17 16:42:37 +08:00 @Fitz 讨论这种未定义行为没有任何意义,开了竞态检测,顺序就可能不同。不同版本的调度器也有可能不同,不同的编译器实现的运行时也可能不同。所以这就是偶然的行为,你的程序是不可以依赖这种未定义行为的。 |