dongzhi2014 2019-03-01 09:41
浏览 86
已采纳

goroutine的执行顺序

I am very new to golang.

My understanding is, All the go-routines will be executed concurrently. both anonymous goroutines will start executing concurrently. but when i run this code, It always prints

a=1 first executed
a=1 second executed
panic: b != 1

Shouldnt it print

a = 1
a = 1 first executed 
Response true
and so on

or

b =1 
b = 1 first executed 
Response true
and so on

Since after sending a value to the channel, the corresponding goroutine should block and wait for the receiver?

 func main() {
            var a, b int
            var c = make(chan bool)
            go func() {
                b = 1
                fmt.Println("b=1 first executed")
                c <- true
                fmt.Println("b=1 second executed")
                if a != 1 { // impossible
                    panic("a != 1") // will never happen
                }
                fmt.Println("b=1 third executed")
            }()
            go func() {
                a = 1
                fmt.Println("a=1 first executed")
                c <- true
                fmt.Println("a=1 second executed")
                if b != 1 { // impossible
                    panic("b != 1") // will never happen
                }
                fmt.Println("a=1 third executed")
            }()

            fmt.Println("Response ", <-c)
            fmt.Println("Main executed")
            }
  • 写回答

2条回答 默认 最新

  • duanfu7004 2019-03-01 10:19
    关注

    I assuming you are running on Playground. There is one thing to keep in mind when using Go Playground: It has a fixed time and a fixed psedo-random generator.

    That means, You can not use Playground to observe random outcomes. And the execuation order of Goroutine, or Go's Concurrency concept in general, is based on uniform psedo-random-ness.

    Running your code on my terminal, it yields different results:

    ➜  basic1 GOMAXPROCS=1 ./basic1
    a=1 first executed
    a=1 second executed
    a=1 third executed
    Response  true
    Main executed
    ➜  basic1 GOMAXPROCS=1 ./basic1
    a=1 first executed
    a=1 second executed
    panic: b != 1
    
    goroutine 6 [running]:
    main.main.func2(0xc000012088, 0xc000054060, 0xc0000120a0)
            /mnt/f/home/leaf/spike/stackoverflow/concur/basic1/main.go:26 +0x13b
    created by main.main
            /mnt/f/home/leaf/spike/stackoverflow/concur/basic1/main.go:20 +0xed
    ➜  basic1 GOMAXPROCS=1 ./basic1
    a=1 first executed
    a=1 second executed
    a=1 third executed
    b=1 first executed
    Response  true
    Main executed
    

    But there's something more. As I have metioned, Go's concurrent excecution order is random. There is no guarantee which goes first, unless there is a synchronization.

    Synchronizations includes channel communicating, and stuffs from sync.

    There is only one synchronization happening in your code, which is communicating through c. It guarantees one thing: when the main() goroutine recieves its Response, at least one of the goroutines spawned there has printed its "excecuated".

    There is no guarantee that which of one is execuated, nor both or only one is execuated, nor whether the goroutine hits the if statement containing panic first.

    Edit:

    Further reading:

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100