猿问

未缓冲通道上的死锁

我目前正在学习go教程的教程,并进入了频道部分,当我做一些测试时,我发现了一个奇怪的行为,我正在努力理解


以下代码生成死锁错误


package main


import "fmt"


func main() {

    c := make(chan string)

    c <- "test"

    fmt.Printf("%v", <- c)

}

但执行以下操作之一可修复代码


使用缓冲通道:


package main


import "fmt"


func main() {

    c := make(chan string, 1)

    c <- "test"

    fmt.Printf("%v", <- c)

}

或将值设置为其他线程上的通道


package main


import "fmt"


func main() {

    c := make(chan string)

    go func(){c <- "test"}()

    fmt.Printf("%v", <- c)

}

第一个版本的代码产生死锁的根本原因是什么?


qq_遁去的一_1
浏览 104回答 2
2回答

ITMISS

只有当有另一个 goroutine 从该通道读取时,写入无缓冲信道才会成功。在第一种情况下,您只有一个 goroutine,即主 goroutine,它写入无缓冲的信道,并且没有其他 goroutine 可以从中读取,因此它是一个死锁。第二个工作,因为通道是缓冲的,并且通过填充缓冲区来成功写入。没有读取的第二次写入将发生死锁。第三个有效,因为写入发生在一个单独的goroutine中,它等待第一个goroutine中的读取运行。

子衿沉夜

由于通道没有缓冲区,因此将阻塞,直到从c读取某些内容。由于读取器在写入后出现,因此永远不会达到读取和死锁。c <- "test"如果通道有缓冲区,则写入缓冲区,而不必等待读取器。然后,读取器从通道缓冲区读取。c <- "test"这一切都是因为读者和作者处于同一个goroutine中,因此必须执行一个接一个的语句。如果读者和作者处于不同的 goroutine 中,则编写者 goroutine 可以阻塞,直到读者 goroutine 阅读。因此,缓冲区通常是不必要的。
随时随地看视频慕课网APP

相关分类

Go
我要回答