fmt.Println的问题与线程打印顺序不一致

时间:2018-05-18 17:09:53

标签: go goroutine

考虑以下代码

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

但我发现这有时只是真的,为什么会这样?

1 个答案:

答案 0 :(得分:3)

您正在做的是:

  1. 启动一些goroutine,等于系统上的CPU数量。
  2. 启动一个额外的goroutine,它会从messages频道读取并打印值。
  3. 等待#1的goroutines终止
  4. 退出
  5. 因为您只是等待第一批goroutine终止,所以无法保证在程序终止之前将打印所有(甚至任何)messages值。