drvpvmz16241016 2018-09-16 03:02
浏览 15

Goroutines的顺序运行

I am learning Golang right now, and came across some interesting tutorial online. for example this one: https://golangbot.com/channels/

in this part about goroutines, there is one example case as following:

package main

import (
    "fmt"
)

func producer(chnl chan int) {
    for i := 0; i < 10; i++ {
        fmt.Println("debugging send...", i)
        chnl <- i
    }
    close(chnl)
}
func main() {
    ch := make(chan int)
    go producer(ch)
    for {
        v, ok := <-ch
        if ok == false {
            break
        }
        fmt.Println("Received ", v, ok)
    }
}

the line fmt.Println("debugging send...", i) is added by me for debugging purpose. and the output is:

debugging send... 0
debugging send... 1
Received  0 true
Received  1 true
debugging send... 2
debugging send... 3
Received  2 true
Received  3 true
debugging send... 4
debugging send... 5
Received  4 true
Received  5 true
debugging send... 6
debugging send... 7
Received  6 true
Received  7 true
debugging send... 8
debugging send... 9
Received  8 true
Received  9 true

The output order seems interesting for me, but can't fully understand what's going on under the hood.

  • 写回答

2条回答 默认 最新

  • douguan1887 2018-09-16 04:50
    关注

    The only places where there's synchronization is the channel operations. There need not be correlation between the order of operations in the goroutines outside of those statements.

    Running your program multiple times, I got the output you have most of the time but sometimes I saw something like this as well:

    debugging send... 0
    debugging send... 1
    Received  0 true
    Received  1 true
    debugging send... 2
    debugging send... 3
    Received  2 true
    Received  3 true
    debugging send... 4
    debugging send... 5
    Received  4 true
    Received  5 true
    debugging send... 6
    debugging send... 7
    Received  6 true
    debugging send... 8
    Received  7 true
    Received  8 true
    debugging send... 9
    Received  9 true
    

    Try running this Bash shell script to run the program multiple times and compare its output:

    #!/bin/bash
    
    # c.go has your Go program
    go run c.go > first.txt
    cat first.txt
    
    echo "======"
    while :; do
        go run c.go > run.txt
        if ! diff -q run.txt first.txt; then
            break
        fi
    done
    
    cat run.txt
    

    Edit: You may find https://golang.org/ref/mem interesting to read about synchronization in Go.

    评论

报告相同问题?

悬赏问题

  • ¥15 gg加速器加速游戏时,提示不是x86架构
  • ¥15 python按要求编写程序
  • ¥15 Python输入字符串转化为列表排序具体见图,严格按照输入
  • ¥20 XP系统在重新启动后进不去桌面,一直黑屏。
  • ¥15 opencv图像处理,需要四个处理结果图
  • ¥15 无线移动边缘计算系统中的系统模型
  • ¥15 深度学习中的画图问题
  • ¥15 java报错:使用mybatis plus查询一个只返回一条数据的sql,却报错返回了1000多条
  • ¥15 Python报错怎么解决
  • ¥15 simulink如何调用DLL文件