gpt4 book ai didi

go - 为什么有些 channel 操作会阻塞而有些不会

转载 作者:行者123 更新时间:2023-12-01 22:38:02 26 4
gpt4 key购买 nike

我一直看到一些文章(和 golang 自己的文档)描述 channel 操作的方式与我在现实中看到的不一致。

它与 Go 如何阻塞 channel 读/写有关。我现在在多个地方读到,当一个 goroutine 看到对 channel 的读取或写入时,它会阻止执行,这意味着它要么等待接收数据,要么等待另一个 goroutine 从 channel 接收数据。

但是,如果您查看以下示例,这显然不是第二次写入发生的情况。

package main

import (
"fmt"
)

func firstFunc(ch chan string) {
fmt.Println("firstFunc Hello", <-ch)
fmt.Println("firstFunc() carries on getting called")
}

func secondFunc(ch chan string) {
fmt.Println("secondFunc Hello", <-ch)
fmt.Println("secondFunc() carries on getting called")
}

func main() {
fmt.Println("main() started")
c1 := make(chan string)
c2 := make(chan string)

go firstFunc(c1)
go secondFunc(c2)

c1 <- "John"
c2 <- "Bob"

fmt.Println("main() ended")
}


这就是我解释 Go 执行此代码的方式:
  • 它打印 main() 开始的消息,创建 channel c1 和 c2 并将 firstFunc 和 secondFunc goroutine 排队(但此时不执行它们)
  • 它到达 c1 <- "John"并阻止它,直到另一个 goroutine 从该 channel 读取
  • 此时它调度 firstFunc 从 c1 读取并继续执行其余代码,直到函数结束
  • main() 再次被重新安排,下一行是 C2 <- "Bob",此时我认为 main() 应该再次阻塞,就像它对 "John"所做的那样,并等待 secondFunc 在继续之前从中读取。但这不是发生的事情。输出:
  • main() started
    firstFunc Hello John
    firstFunc() carries on getting called
    main() ended

    它不会简单地阻止对“Bob”的写入,而是继续执行直到 main() 完成并且从不调度 secondFunc。

    这现在已经成为我学习 Go 的一个障碍,因为我不确定是我不能信任的文章还是我的理解存在差距。

    我将不胜感激这方面的一些帮助。

    最佳答案

    一个无缓冲的 channel 写入将阻塞,直到另一个 goroutine 从中读取。发生这种情况时,读取和写入 goroutine 都会启用。之后,无法保证执行将如何进行。

    在您的示例中,在 firstFunc 之后从 channel 读取,它会运行直到完成。主 goroutine 写入 channel 二,启用 secondFunc ,但在它有机会完成编写之前,main goroutine 就结束了。

    这里的问题是有许多可能的执行顺序,而您碰巧观察到一种特定的顺序。

    关于go - 为什么有些 channel 操作会阻塞而有些不会,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61686930/

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