2 回答

TA貢獻(xiàn)1776條經(jīng)驗(yàn) 獲得超12個(gè)贊
OP更新問題后更新答案
您可以只循環(huán)地圖中的所有鍵,也許還有另一個(gè) goroutine 不斷循環(huán)所有鍵。顯然,如果一個(gè)鍵沒有被初始化,那么它就不會(huì)出現(xiàn)在 for range 循環(huán)中。對(duì)于每個(gè)鍵,您可以啟動(dòng)一個(gè)監(jiān)聽的 goroutine,這樣它就不會(huì)阻塞,或者您可以使用緩沖通道,這樣它們就不會(huì)阻塞到緩沖區(qū)限制。您也可以最好使用 waitGroup,而不是 time.Sleep(),這些僅用于這個(gè)簡(jiǎn)單的示例。
package main
import (
"fmt"
"time"
)
func main() {
m := make(map[int]chan string)
go func() {
m[0] = make(chan string)
m[0] <- "abab"
}()
time.Sleep(time.Second * 1) //sleep so the above goroutine initializes the key 0 channel
for key := range m{ //loop on all non-nil keys
fmt.Println(key)
go func(k int){ // goroutine to listen on this channel
fmt.Println(<- m[k])
}(key)
}
time.Sleep(time.Second * 1) //sleep so u can see the effects of the channel recievers
}
舊答案
流量就是這樣。主 goroutine 啟動(dòng)。地圖已創(chuàng)建。主 goroutine 遇到另一個(gè) goroutine。它產(chǎn)生了 goroutine 并繼續(xù)它的生活。然后遇到這條線,fmt.Println(<-m[0]),這是一個(gè)問題,因?yàn)榈貓D確實(shí)初始化了,但是地圖本身的通道沒有初始化!當(dāng)主 goroutine 到達(dá)fmt.Println(<-m[0])時(shí),另一個(gè) goroutine 還沒有初始化通道!所以這是一個(gè)簡(jiǎn)單的修復(fù),只需在生成 goroutine 之前初始化通道,你就可以開始了!
package main
import "fmt"
func main() {
m := make(map[int]chan string)
m[0] = make(chan string)
go func() {
m[0] <- "abab"
}()
fmt.Println(<-m[0])
}
編輯:請(qǐng)注意這fmt.Println(<-m[0])是阻塞的,這意味著如果在另一個(gè) goroutine 中,您不在通道上發(fā)送,您也會(huì)陷入死鎖,因?yàn)槟噲D在沒有人實(shí)際發(fā)送的情況下在通道上接收。

TA貢獻(xiàn)1880條經(jīng)驗(yàn) 獲得超4個(gè)贊
您需要同步通道的創(chuàng)建。
就目前而言,您的主線程到達(dá)時(shí)<-m[0]
仍然m[0]
是一個(gè)未初始化的通道,并且在未初始化的通道上接收永遠(yuǎn)阻塞。
您的 go 例程創(chuàng)建了一個(gè)新通道并將其放入m[0]
,但主要的 go 例程已經(jīng)在偵聽先前的零值。在這個(gè)新通道上發(fā)送也會(huì)永遠(yuǎn)阻塞,因?yàn)樗鼪]有讀取任何內(nèi)容,所以所有 goroutine 都會(huì)阻塞。
要解決這個(gè)問題,請(qǐng)移到m[0] = make(chan string)
你的 go 例程之上,這樣它就會(huì)同步發(fā)生。
- 2 回答
- 0 關(guān)注
- 123 瀏覽
添加回答
舉報(bào)