dongshan4518 2015-05-28 22:33
浏览 18
已采纳

为什么在此通道上不发送阻止?

Consider the following snippet of Go code:

c := make(chan string)

go func() {
    time.Sleep(100 * time.Millisecond)
    fmt.Println("Sending test1...")
    c <- "test1"
    fmt.Println("Sending test2...")
    c <- "test2"
    fmt.Println("Done sending")
}()

go func() {
    for {
        select {
        case n := <-c:
            fmt.Println("Received:", n)
        }
    }
}()

Full source: http://play.golang.org/p/yY6JQzDMvn

I expect that the first goroutine will block when attempting to write "test1" to the channel until the receive in the second goroutine. The expected output would be:

Sending test1...
Received: test1
Sending test2...
Received: test2

However, when I actually run the example, I end up with:

Sending test1...
Sending test2...
Received: test1
Received: test2

It would appear by the output that the send is not blocking as one would expect. What's going on here?

  • 写回答

1条回答 默认 最新

  • dpbvpgvrhwxen3222 2015-05-28 22:39
    关注

    This is caused by a race condition in the two goroutines. By default, the Go runtime uses a single thread for all goroutines, so execution is serialized. Consider the following possible scenario for executing the code above:

    • the first goroutine is blocked by a Sleep() call
    • the second goroutine is blocked waiting for a receive on the channel
    • the first goroutine resumes execution after the Sleep() call ends
    • "test1" is written to the channel, which blocks
    • the second goroutine receives the value but before printing the output, execution switches back to the first goroutine
    • the first goroutine prints "Sending test2..." and writes the second value to the channel which again blocks
    • the second goroutine resumes where it was preempted and prints the "Received: test1" message
    • the loop is executed again and receives the second value

    In summary, the send is indeed blocking, it just doesn't appear to be due to the order of output.

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

报告相同问题?

悬赏问题

  • ¥20 基于MSP430f5529的MPU6050驱动,求出欧拉角
  • ¥20 Java-Oj-桌布的计算
  • ¥15 powerbuilder中的datawindow数据整合到新的DataWindow
  • ¥20 有人知道这种图怎么画吗?
  • ¥15 pyqt6如何引用qrc文件加载里面的的资源
  • ¥15 安卓JNI项目使用lua上的问题
  • ¥20 RL+GNN解决人员排班问题时梯度消失
  • ¥60 要数控稳压电源测试数据
  • ¥15 能帮我写下这个编程吗
  • ¥15 ikuai客户端l2tp协议链接报终止15信号和无法将p.p.p6转换为我的l2tp线路