簡體   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