golang所有goroutine都处于睡眠状态-死锁

时间:2020-04-04 04:26:06

标签: go deadlock channel

运行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!

3 个答案:

答案 0 :(得分:1)

c1的写操作将永远不会执行,因为对c1的读操作是在wg.Wait()之后进行的,直到写入c1为止,该操作将停止。因此,主goroutine在wg.Wait()等待,而嵌套goroutine在c1写等待。

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

答案 1 :(得分:0)

在Golang中,无缓冲通道上的写操作被阻止。从文档中很明显。

您的执行被阻止在

c1 <- "one"

推迟的陈述

defer wg.Done()

从不执行。

答案 2 :(得分:0)

在您的代码中,您正在使用一个未缓冲的通道,该通道会阻塞直到接收器收到“一个”为止。在这种情况下,代码不会越过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")
}