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条)

报告相同问题?

悬赏问题

  • ¥50 易语言把MYSQL数据库中的数据添加至组合框
  • ¥20 求数据集和代码#有偿答复
  • ¥15 关于下拉菜单选项关联的问题
  • ¥20 java-OJ-健康体检
  • ¥15 rs485的上拉下拉,不会对a-b<-200mv有影响吗,就是接受时,对判断逻辑0有影响吗
  • ¥15 使用phpstudy在云服务器上搭建个人网站
  • ¥15 应该如何判断含间隙的曲柄摇杆机构,轴与轴承是否发生了碰撞?
  • ¥15 vue3+express部署到nginx
  • ¥20 搭建pt1000三线制高精度测温电路
  • ¥15 使用Jdk8自带的算法,和Jdk11自带的加密结果会一样吗,不一样的话有什么解决方案,Jdk不能升级的情况