我在爭論 goroutine 并讓他們與主要 goroutine 上的頻道進行交流時遇到了麻煩。為簡化起見,我的代碼如下所示:
func main() {
channel := make(chan string)
var wg sync.WaitGroup
for i := 0; i < 10; i {
wg.Add(1)
go performTest(channel, &wg, i)
}
wg.Wait()
close(channel)
for line := range channel {
fmt.Print(line)
}
}
func performTest(channel chan string, wg *sync.WaitGroup, i int) {
defer wg.Done()
// perform some work here
result := fmt.sprintf("Pretend result %d", i)
channel <- result
}
這似乎進入了某種僵局,但我不明白為什么。它卡住了wg.Wait(),即使我希望它在所有 goroutine 都呼叫Done等待組后繼續。我在這里想念什么?我想等待 goroutines,然后遍歷通道中的所有結果。
uj5u.com熱心網友回復:
您可以等待組并在單獨的 go 例程中關閉通道。如果通道關閉,您在通道上的范圍將在收到最后一個發送的值后結束。
如果您只是等待,則不會從頻道收到任何內容。由于通道是無緩沖的,performTestgoroutines 將無法發送。對于無緩沖通道,發送操作將阻塞,直到它被接收。因此,延遲wg.Done呼叫永遠不會發生,您的程式就會陷入僵局。由于Done僅在執行永久阻塞發送后呼叫。
func main() {
channel := make(chan string)
var wg sync.WaitGroup
for i := 0; i < 10; i {
wg.Add(1)
go performTest(channel, &wg, i)
}
// this is the trick
go func() {
wg.Wait()
close(channel)
}()
for line := range channel {
fmt.Print(line)
}
}
func performTest(channel chan string, wg *sync.WaitGroup, i int) {
defer wg.Done()
// perform some work here
result := fmt.Sprintf("Pretend result %d\n", i)
channel <- result
}
https://play.golang.com/p/5pACJzwL4Hi
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/422095.html
標籤:
