2 回答

TA貢獻(xiàn)1776條經(jīng)驗 獲得超12個贊
OP更新問題后更新答案
您可以只循環(huán)地圖中的所有鍵,也許還有另一個 goroutine 不斷循環(huán)所有鍵。顯然,如果一個鍵沒有被初始化,那么它就不會出現(xiàn)在 for range 循環(huán)中。對于每個鍵,您可以啟動一個監(jiān)聽的 goroutine,這樣它就不會阻塞,或者您可以使用緩沖通道,這樣它們就不會阻塞到緩沖區(qū)限制。您也可以最好使用 waitGroup,而不是 time.Sleep(),這些僅用于這個簡單的示例。
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 啟動。地圖已創(chuàng)建。主 goroutine 遇到另一個 goroutine。它產(chǎn)生了 goroutine 并繼續(xù)它的生活。然后遇到這條線,fmt.Println(<-m[0]),這是一個問題,因為地圖確實初始化了,但是地圖本身的通道沒有初始化!當(dāng)主 goroutine 到達(dá)fmt.Println(<-m[0])時,另一個 goroutine 還沒有初始化通道!所以這是一個簡單的修復(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])
}
編輯:請注意這fmt.Println(<-m[0])是阻塞的,這意味著如果在另一個 goroutine 中,您不在通道上發(fā)送,您也會陷入死鎖,因為您試圖在沒有人實際發(fā)送的情況下在通道上接收。

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