dongquelu1239 2018-05-18 17:09
浏览 128
已采纳

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

Consider the following code

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()
}

And the following last couple of line output

980100
982081
984064
true
988036
990025
992016
994009
996004
998001
1000000

Since message <- true is always at the end of a for loop and

    for i := range messages {
        fmt.Println(i)
    }

prints after the channel receive the message.

I expect true to be printed always at the end like

988036
990025
992016
994009
996004
998001
1000000
true

But I find that is only sometimes true, why is that?

  • 写回答

1条回答 默认 最新

  • doujiaochan7317 2018-05-18 17:36
    关注

    What you're doing is:

    1. Start a number of goroutines, equal to the number of CPUs on your system.
    2. Start one additional goroutine, which reads and prints the values from the messages channel.
    3. Wait for the goroutines from #1 to terminate
    4. Exit

    Because you're only waiting for the first batch of goroutines to terminate, there is no guarantee that all (or even any) of the messages values will be printed before the program terminates.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 多址通信方式的抗噪声性能和系统容量对比
  • ¥15 winform的chart曲线生成时有凸起
  • ¥15 msix packaging tool打包问题
  • ¥15 finalshell节点的搭建代码和那个端口代码教程
  • ¥15 Centos / PETSc / PETGEM
  • ¥15 centos7.9 IPv6端口telnet和端口监控问题
  • ¥20 完全没有学习过GAN,看了CSDN的一篇文章,里面有代码但是完全不知道如何操作
  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
  • ¥20 海浪数据 南海地区海况数据,波浪数据
  • ¥20 软件测试决策法疑问求解答