gpt4 book ai didi

go - 为什么不阻塞此 channel 上的发送?

转载 作者:IT王子 更新时间:2023-10-29 01:33:33 30 4
gpt4 key购买 nike

考虑以下 Go 代码片段:

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

完整来源: http://play.golang.org/p/yY6JQzDMvn

我希望第一个 goroutine 在尝试将 "test1" 写入 channel 时会阻塞,直到第二个 goroutine 接收为止。预期的输出将是:

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

然而,当我实际运行该示例时,我最终得到:

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

从输出看来,发送并没有像人们预期的那样阻塞。这是怎么回事?

最佳答案

这是由两个 goroutine 中的竞争条件引起的。默认情况下,Go 运行时对所有 goroutine 使用单个线程,因此执行是序列化的。考虑以下执行上述代码的可能场景:

  • 第一个 goroutine 被 Sleep() 调用阻塞
  • 第二个 goroutine 被阻塞等待 channel 上的接收
  • 第一个 goroutine 在 Sleep() 调用结束后恢复执行
  • "test1" 被写入 channel ,阻塞
  • 第二个 goroutine 收到值但在打印输出之前,执行切换回第一个 goroutine
  • 第一个 goroutine 打印 "Sending test2..." 并将第二个值写入再次阻塞的 channel
  • 第二个 goroutine 在它被抢占的地方恢复并打印 "Received: test1" 消息
  • 循环再次执行并接收第二个值

综上所述,send确实是阻塞的,只是看起来不是输出顺序的问题。

关于go - 为什么不阻塞此 channel 上的发送?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30518166/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com