fmt.Println 问题与线程打印顺序不一致
Issue with fmt.Println not consistent with thread printing order
考虑以下代码
package main
import (
"fmt"
"runtime"
"sync"
)
func main() {
messages := make(chan bool)
var wg sync.WaitGroup
var x = 1000
wg.Add(runtime.NumCPU())
for i := 0; i < runtime.NumCPU(); i++ {
go func(x int) {
defer wg.Done()
var i = 0
for i < x {
i += 1
fmt.Println(i * i)
}
messages <- true
}(x)
}
go func() {
for i := range messages {
fmt.Println(i)
}
}()
wg.Wait()
}
以及下面最后几行输出
980100
982081
984064
true
988036
990025
992016
994009
996004
998001
1000000
因为 message <- true
总是在 for 循环的末尾并且
for i := range messages {
fmt.Println(i)
}
频道收到消息后打印。
我希望 true
像
一样总是打印在最后
988036
990025
992016
994009
996004
998001
1000000
true
但我发现这只是有时是正确的,为什么呢?
您正在做的是:
- 启动多个 goroutine,数量等于系统上的 CPU 数量。
- 启动一个额外的 goroutine,它从
messages
通道读取并打印值。
- 等待来自#1 的 goroutines 终止
- 退出
因为您只是在等待第一批 goroutine 终止,所以不能保证在程序终止之前打印所有(甚至任何)messages
值。
考虑以下代码
package main
import (
"fmt"
"runtime"
"sync"
)
func main() {
messages := make(chan bool)
var wg sync.WaitGroup
var x = 1000
wg.Add(runtime.NumCPU())
for i := 0; i < runtime.NumCPU(); i++ {
go func(x int) {
defer wg.Done()
var i = 0
for i < x {
i += 1
fmt.Println(i * i)
}
messages <- true
}(x)
}
go func() {
for i := range messages {
fmt.Println(i)
}
}()
wg.Wait()
}
以及下面最后几行输出
980100
982081
984064
true
988036
990025
992016
994009
996004
998001
1000000
因为 message <- true
总是在 for 循环的末尾并且
for i := range messages {
fmt.Println(i)
}
频道收到消息后打印。
我希望 true
像
988036
990025
992016
994009
996004
998001
1000000
true
但我发现这只是有时是正确的,为什么呢?
您正在做的是:
- 启动多个 goroutine,数量等于系统上的 CPU 数量。
- 启动一个额外的 goroutine,它从
messages
通道读取并打印值。 - 等待来自#1 的 goroutines 终止
- 退出
因为您只是在等待第一批 goroutine 终止,所以不能保证在程序终止之前打印所有(甚至任何)messages
值。