繁体   English   中英

golang所有goroutines都睡着了 - 死锁

[英]golang all goroutines are asleep - deadlock

运行跟随 golang 片段时出现错误。 我认为进度将在 wg.Wait() 处阻塞,直到 go 例程结束。 那么该值将从 c1 获得。 但它可能不会按预期进行。

func main() {

c1 := make(chan string)
//var c1 chan string
var wg sync.WaitGroup

wg.Add(1)
go func() {
    defer wg.Done()
    fmt.Printf("go routine begin\n")
    time.Sleep(1 * time.Second)
    c1 <- "one"
    fmt.Printf("go routine done\n")
}()
wg.Wait()
fmt.Printf("done c1: %v\n", <-c1)
fmt.Printf("out\n")
}

错误信息是,

 go routine begin
 fatal error: all goroutines are asleep - deadlock!

c1的写入永远不会执行,因为从c1读取是在wg.Wait()之后,它将停止直到c1被写入。 所以主 goroutine 在wg.Wait()处等待,而嵌套 goroutine 在c1 write 处等待。

您可以使通道缓冲,或等待c1在单独的 goroutine 上读取。

在 Golang 中,无缓冲通道上的写操作是阻塞的。 从文档中可以清楚地看到。

您的执行被阻止在

c1 <- "one"

延期声明

defer wg.Done()

从不执行。

在您的代码中,您正在使用一个无缓冲的通道,该通道会阻塞直到接收器接收到“一个”。 在这种情况下,代码不会 go 超过 wg.Wait() 因为 wg.Done() 永远不会被执行。

我想这就是你所追求的。

func main() {

c1 := make(chan string)
//var c1 chan string

go func() {
    fmt.Printf("go routine begin\n")
    time.Sleep(1 * time.Second)
    c1 <- "one"
    fmt.Printf("go routine done\n")
}()
fmt.Printf("done c1: %v\n", <-c1)
fmt.Printf("out\n")
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM