我一直看到一些文章(和 golang 自己的文档)描述通道操作的方式与我在现实中看到的不一致。
它与 Go 如何阻塞通道读/写有关。我现在在多个地方读到,当一个 goroutine 看到对通道的读取或写入时,它会阻止执行,这意味着它要么等待接收数据,要么等待另一个 goroutine 从通道接收数据。
但是,如果您查看以下示例,这显然不是第二次写入发生的情况。
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() 开始的消息,创建通道 c1 和 c2 并将 firstFunc 和 secondFunc goroutine 排队(但此时不执行它们)
它到达 c1 <- "John" 并阻止它,直到另一个 goroutine 从该通道读取
此时它调度 firstFunc 从 c1 读取并继续执行其余代码直到函数结束
main() 再次被重新安排,下一行是 C2 <- "Bob",此时我认为 main() 应该再次阻塞,就像它对 "John" 所做的那样,并等待 secondFunc 在继续之前从中读取。但这不是发生的事情。输出:
main() started
firstFunc Hello John
firstFunc() carries on getting called
main() ended
它不会简单地阻止对“Bob”的写入,而是继续执行直到 main() 完成并且从不调度 secondFunc。
现在这已经成为我学习 Go 的一个障碍,因为我不确定是我不能信任的文章还是我的理解存在差距。
我将不胜感激这方面的一些帮助。
红颜莎娜
largeQ
长风秋雁
相关分类