我是 Golang 的新手,并試圖了解 Golang 中的 WaitGroups 和并發性是如何作業的。在此示例中,創建了 5 個作業人員,并帶有一個將作業傳遞給每個作業人員的通道。讓工人睡眠 1 秒鐘以模擬繁重的計算。一切順利,但程式并沒有優雅地退出。而是列印此錯誤訊息。請幫助理解為什么會發生這種情況。
fatal error: all goroutines are asleep - deadlock!
這是代碼,
import (
"fmt"
"sync"
"time"
)
func worker(wg *sync.WaitGroup, messageChannel <-chan string) {
defer wg.Done()
for i := range messageChannel {
time.Sleep(time.Second)
fmt.Println("done processing - ", i)
}
}
func stop(wg *sync.WaitGroup) {
fmt.Println("waiting on the main thread")
wg.Wait()
}
func main() {
wg := new(sync.WaitGroup)
messageChannel := make(chan string, 50)
// create workers
for i := 0; i < 5; i {
wg.Add(1)
go worker(wg, messageChannel)
}
// input some messages
for i := 0; i < 10; i {
messageChannel <- fmt.Sprint(i)
}
stop(wg)
close(messageChannel)
}
提前致謝!
uj5u.com熱心網友回復:
為了擴展@Peter 的評論,這里是您撰寫的代碼的執行流程:
- 初始化后,您啟動
workergoroutine。每個workergoroutine 都會跨越messageChannel1 秒的時間延遲列印出一條訊息。 - 接下來,
messageChannel通過 for 回圈插入一些訊息。每個可用的workergoroutine 都會收到一條訊息,直到所有訊息都被處理并列印出來。之后,workergoroutine 等待來自messageChannel. - 在用于在 中插入訊息的 for 回圈
messageChannel完成后,您執行該stop函式,該函式阻塞wg.Wait()并等待wg.Done()所有workergoroutine 中的所有呼叫執行。但是,由于messageChannel沒有關閉,沒有一個workergoroutine 可以完成執行,也沒有執行任何wg.Done()呼叫。 - 該
worker夠程被卡住,因為messageChannel永遠不會關閉,該main夠程被卡住,因為的wg.Wait()內部通話stop功能,和你結束了一個僵局,所有夠程都睡著了。
根據建議,您只需要交換位置stop和close呼叫
//rest of the code
close(messageChannel)
stop(wg)
這樣,當所有訊息都插入 中時messageChannel,您呼叫close(messageChannel)和 then stop(wg),這會阻止wg.Wait呼叫。該close(messageChannel)呼叫確保,一旦從 中讀取所有訊息messageChannel,goroutine內部的for-range回圈將退出,并且所有呼叫都將被執行。一旦發生這種情況,將解除阻塞,程式將正確完成執行。messageChannelworkerdefer wg.Done()wg.Wait()
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/339723.html
下一篇:golang中的正則運算式匹配
