2 回答

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超6個(gè)贊
for ... range只有在從通道接收到所有值并且通道已關(guān)閉時(shí),通道才會(huì)終止。
在您的示例中,您希望在延遲函數(shù)中關(guān)閉通道,但這只會(huì)在main()返回時(shí)運(yùn)行。但main()只有在循環(huán)結(jié)束時(shí)才會(huì)返回。這就是死鎖的原因。for循環(huán)等待通道關(guān)閉,關(guān)閉通道等待 for 循環(huán)結(jié)束。
當(dāng)您使用循環(huán)從通道中準(zhǔn)確接收 5 個(gè)值時(shí),它會(huì)起作用,因?yàn)閱?dòng)的 goroutines 會(huì)在其上發(fā)送 5 個(gè)值。此循環(huán)不會(huì)等待通道關(guān)閉,因此循環(huán)可以結(jié)束,main()函數(shù)也可以結(jié)束。
這就是為什么發(fā)送者應(yīng)該關(guān)閉通道(而不是接收者),并且問(wèn)題立即得到解決:
func sendValues(myIntChannel chan int) {
for i := 0; i < 5; i++ {
myIntChannel <- i //sending value
}
close(myIntChannel)
}
func main() {
myIntChannel := make(chan int)
go sendValues(myIntChannel)
for value := range myIntChannel {
fmt.Println(value) //receiving value
}
}
輸出(在Go Playground上試試):
0
1
2
3
4

TA貢獻(xiàn)1811條經(jīng)驗(yàn) 獲得超5個(gè)贊
用不同的術(shù)語(yǔ)來(lái)解釋它,您的代碼所做的是:
func main() {
...
while myIntChannel is not closed {
...
}
close myIntChannel
}
現(xiàn)在你可以看到死鎖是從哪里來(lái)的。
雖然上述答案是有效的,但如果您更喜歡使用,您也可以試試這個(gè)defer:
func sendValues(myIntChannel chan int) {
defer close(myIntChannel)
for i := 0; i < 5; i++ {
myIntChannel <- i //sending value
}
}
func main() {
myIntChannel := make(chan int)
go sendValues(myIntChannel)
for value := range myIntChannel {
fmt.Println(value) //receiving value
}
}
- 2 回答
- 0 關(guān)注
- 168 瀏覽
添加回答
舉報(bào)