我目前正在学习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中的读取运行。
子衿沉夜
TA贡献1828条经验 获得超3个赞
由于通道没有缓冲区,因此将阻塞,直到从c读取某些内容。由于读取器在写入后出现,因此永远不会达到读取和死锁。c <- "test"
如果通道有缓冲区,则写入缓冲区,而不必等待读取器。然后,读取器从通道缓冲区读取。c <- "test"
这一切都是因为读者和作者处于同一个goroutine中,因此必须执行一个接一个的语句。如果读者和作者处于不同的 goroutine 中,则编写者 goroutine 可以阻塞,直到读者 goroutine 阅读。因此,缓冲区通常是不必要的。
- 2 回答
- 0 关注
- 62 浏览
添加回答
举报
0/150
提交
取消