第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么這段 Golang 代碼會產(chǎn)生死鎖?

為什么這段 Golang 代碼會產(chǎn)生死鎖?

Go
慕絲7291255 2022-10-10 16:08:48
我是 Golang 的新手,我很難弄清楚為什么下面的代碼會產(chǎn)生死鎖。另外,我該如何修復(fù)它才能正常工作?    package main        import "fmt"        func main() {        m := make(map[int]chan string)        go func() {            m[0] = make(chan string)            m[0] <- "abab"        }()        fmt.Println(<-m[0])    }編輯:感謝您的回答!m[0]不幸的是,初始化m[0] = make(chan string)在啟動一個新的 goroutine 之前并不是我想要的。我的問題是:有沒有辦法“動態(tài)”創(chuàng)建頻道?例如,我有一個m類型的地圖,map[int]chan string我收到包含類似id類型的請求int。我想通過 channel 發(fā)送消息map[id],但是為每個通道初始化通道int成本太高。我該如何解決/解決這個問題?因此,換句話說,我想為每個隊列創(chuàng)建一個單獨的作業(yè)隊列,id并懶惰地初始化每個隊列。
查看完整描述

2 回答

?
叮當(dāng)貓咪

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ā)送的情況下在通道上接收。


查看完整回答
反對 回復(fù) 2022-10-10
?
慕村225694

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ā)生。


查看完整回答
反對 回復(fù) 2022-10-10
  • 2 回答
  • 0 關(guān)注
  • 113 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號