为了账号安全,请及时绑定邮箱和手机立即绑定

如何向golang初学者解释通道阻塞机制?

如何向golang初学者解释通道阻塞机制?

Go
泛舟湖上清波郎朗 2022-09-05 10:56:44
我是一个golang初学者,在学习频道和日常工作时遇到了一些麻烦。我的一个卡住点是golang通道阻止机制是如何工作的。在golang tour中,它说我用我的理解做了一些实验,并达到了结果,.这些提示并没有真正让我对错误是如何发生的了解。我用谷歌搜索过它,但我得到的几乎每篇文章都是关于渠道的深层机制,或者它假设读者理解了单个单词已经给出了所有的信息。By default, sends and receives block until the other side is ready.fatal error: all goroutines are asleep - deadlock!block但作为一个初学者,我有很多疑问,比如:同一 go-routine 能否在写入通道后执行通道读取操作?如果某个通道被阻塞,其他 go-routine 还能向它发送消息吗?如果 go-routine 尝试将消息发送到被阻止的通道,会发生什么情况?它会通过错误,还是什么也没发生,或者?以下是我的一个让我感到困惑的测试?(据我所知,main func是一个go-routine,我认为它的执行是相同的)package mainimport "time"func chanWrite(s string, ch chan string) {    ch <- s    println("write", s)}func chanRead(ch chan string) {    println("read", <- ch)}// main func 1func main() {    ch := make(chan string)    go chanWrite("A", ch)    time.Sleep(time.Second)}// main func 1 didn't throw error// main func 2(modify main func 1 and then execute it)func main() {    ch := make(chan string)    chanWrite("A", ch)    time.Sleep(time.Second)}// main func 2 throw error: "fatal error: all goroutines are asleep - deadlock!"我在这个测试中看到的是在某些情况下,当我在没有阅读的情况下将内容写入通道时,我得到了,有时什么也没发生(例如在main func 1中)。fatal error那么,有人可以以一种简单而深入的方式解释通道块是如何工作的,以便golang初学者可以轻松理解它吗?
查看完整描述

2 回答

?
慕的地6264312

TA贡献1817条经验 获得超6个赞

goroutine 可以阻止等待通道准备好发送或接收,但通道本身永远不会处于“阻塞”状态。

第一个程序不会死机,因为 main 函数执行到最后并终止程序。

同一 go-routine 能否在写入通道后执行通道读取操作?

否,如果通道未缓冲(默认值)。对于无缓冲信道,发送 goroutine 会阻塞,直到接收 goroutine 准备就绪。

单个 goroutine 不能同时执行发送和接收。如果只有一个 goroutine 发送到通道,则 goroutine 会永远阻塞。

如果某个通道被阻塞,其他 go-routine 还能向它发送消息吗?

goroutine 可以在通道关闭之前的任何时间将值发送到通道。Goroutine 可以阻止等待通道准备好发送。

如果 go-routine 尝试将消息发送到被阻止的通道,会发生什么情况?它会通过错误,还是什么也没发生,或者?

Goroutine可以阻止等待频道准备就绪。通道本身未处于阻塞状态。


查看完整回答
反对 回复 2022-09-05
?
撒科打诨

TA贡献1934条经验 获得超2个赞

通道不会“阻塞”。通道上的读取或写入操作可能会阻塞。

对于无缓冲通道(这是您上面的内容):写入操作将阻止写入 goroutine,直到另一个 goroutine 准备好从该通道读取。当读取 goroutine 准备好读取(即执行 <-ch)时,则写入和读取发生,并且两个 goroutine 继续运行。

对于缓冲通道:只要通道缓冲区未满,写入操作就不会阻塞。同样,如果有要从通道读取的内容,则读取不会阻塞。

至于你的问题:

  1. 如果所讨论的通道未缓冲,则写入操作将阻塞,因为只有当另一个 goroutine 正在从该通道读取时,写入操作才能继续。因此,goroutine不会进展为从通道读取。如果这是一个缓冲通道,并且通道未满,则相同的 goroutine 可以写入该通道并从中读取。

  2. 如果一个 goroutine 正在等待写入一个通道,而另一个 goroutine 来写入它,它也会阻塞,直到另一个 goroutine 从通道读取。

  3. 如果 goroutine 尝试写入已满的通道,它将阻塞,直到另一个 goroutine 可以从该通道读取。


查看完整回答
反对 回复 2022-09-05
  • 2 回答
  • 0 关注
  • 68 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信