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

未缓冲通道上的死锁

未缓冲通道上的死锁

Go
qq_遁去的一_1 2022-09-05 09:16:31
我目前正在学习go教程的教程,并进入了频道部分,当我做一些测试时,我发现了一个奇怪的行为,我正在努力理解以下代码生成死锁错误package mainimport "fmt"func main() {    c := make(chan string)    c <- "test"    fmt.Printf("%v", <- c)}但执行以下操作之一可修复代码使用缓冲通道:package mainimport "fmt"func main() {    c := make(chan string, 1)    c <- "test"    fmt.Printf("%v", <- c)}或将值设置为其他线程上的通道package mainimport "fmt"func main() {    c := make(chan string)    go func(){c <- "test"}()    fmt.Printf("%v", <- c)}第一个版本的代码产生死锁的根本原因是什么?
查看完整描述

2 回答

?
ITMISS

TA贡献1871条经验 获得超8个赞

只有当有另一个 goroutine 从该通道读取时,写入无缓冲信道才会成功。在第一种情况下,您只有一个 goroutine,即主 goroutine,它写入无缓冲的信道,并且没有其他 goroutine 可以从中读取,因此它是一个死锁。

第二个工作,因为通道是缓冲的,并且通过填充缓冲区来成功写入。没有读取的第二次写入将发生死锁。

第三个有效,因为写入发生在一个单独的goroutine中,它等待第一个goroutine中的读取运行。


查看完整回答
反对 回复 2022-09-05
?
子衿沉夜

TA贡献1828条经验 获得超3个赞

由于通道没有缓冲区,因此将阻塞,直到从c读取某些内容。由于读取器在写入后出现,因此永远不会达到读取和死锁。c <- "test"

如果通道有缓冲区,则写入缓冲区,而不必等待读取器。然后,读取器从通道缓冲区读取。c <- "test"

这一切都是因为读者和作者处于同一个goroutine中,因此必须执行一个接一个的语句。如果读者和作者处于不同的 goroutine 中,则编写者 goroutine 可以阻塞,直到读者 goroutine 阅读。因此,缓冲区通常是不必要的。


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

添加回答

举报

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