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

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

無法處理 goroutine 死鎖

無法處理 goroutine 死鎖

Go
繁星點點滴滴 2022-04-26 15:34:38
我正在嘗試向頻道廣播一條消息,我只希望它發(fā)送 5 條消息。但我總是得到這個錯誤: 致命錯誤:所有goroutines都睡著了 - 死鎖!我的代碼:package mainimport (    "log"    "sync"    broadcast "github.com/dustin/go-broadcast"    "github.com/pwaller/barrier")//Message boradcastedtype Message struct {    y string    x int}var w sync.WaitGroupvar bar barrier.Barrierfunc main() {    b := broadcast.NewBroadcaster(100)    w.Add(1)    go workerOne(b)    d := Message{"message :", 0}    go func() {        for i := 0; i < 5; i++ {            d.x = i            log.Printf("Sending %v", d)            b.Submit(d)        }        <-bar.Barrier()        b.Close()    }()    w.Wait()}func workerOne(b broadcast.Broadcaster) {    ch := make(chan interface{})    b.Register(ch)    for {        v, ok := <-ch        if ok {            log.Printf("workerOne() reading : %v", v)        } else {            log.Printf("i am here")            close(ch)            b.Unregister(ch)            bar.Fall()            w.Done()            return        }    }}我嘗試了一切,但它沒有拋出條件!在workerOne()函數(shù)中確定以關閉通道并結(jié)束等待,但仍然有相同的錯誤
查看完整描述

1 回答

?
慕容3067478

TA貢獻1773條經(jīng)驗 獲得超3個贊

正如Adrian 在評論中指出的那樣barrier,您正在使用的包已被棄用,取而代之的是 Go 包含的context包。你應該context改用。(目前,broadcast您使用的軟件包也對您沒有任何好處。)


不過,眼前的問題似乎很明顯:運行的(單個)goroutineworkerOne從一個通道讀取數(shù)據(jù),并且只有當通道關閉(因此ok變?yōu)閒alse)時,它才會調(diào)用bar.Fall()以消除障礙。同時,運行匿名發(fā)送者函數(shù)的(單個)goroutine:


go func() {

    for i := 0; i < 5; i++ {

        d.x = i

        log.Printf("Sending %v", d)

        b.Submit(d)

    }

    <-bar.Barrier()

    b.Close()

}()

通過包的(非常)簡單的消息發(fā)布/訂閱接口提交五個項目broadcast,然后等待障礙下降。唯一能打破障礙的goroutine——把它想象成唯一可以在這里救你的gopher——是 running workerOne。他現(xiàn)在正在頻道接收中等待:


    v, ok := <-ch

你,在你的主 goroutine 中,正在通過你的sync.WaitGroup變量等待:


w.Wait()

運行匿名發(fā)送函數(shù)的 gopher 正在等待:


    <-bar.Barrier()

誰——這三個在各種 Go 例程中運行或等待的 gopher 中的哪一個——將向匿名發(fā)送者中的 gopher 發(fā)出信號,v, ok := <-ch應該得到!ok結(jié)果?唯一能做到的就是跑的地鼠workerOne,但他被困住了。


該broadcast軟件包永遠不會為您關閉您的頻道。取消注冊頻道只是將其從廣播公司的輸出頻道中刪除,這會使未注冊的頻道保持打開狀態(tài);并且完全有效地關閉廣播公司只是取消注冊所有頻道,再次讓它們保持打開狀態(tài)。因此,如果您希望關閉您的頻道,您必須自己在其他地方執(zhí)行此操作。


或者,您可以修改您的workerOne,使其不依賴于正在關閉的通道。例如,你的變量d有一個x int和一個y string; 你可以選擇其中一個或兩個,并決定一個字符串值“放下障礙”——也許還有一些特定int的值——意味著“bar.Fall()現(xiàn)在調(diào)用”。但是,如果您這樣做,那么您從這兩個非標準軟件包中獲得的收益會更少。


查看完整回答
反對 回復 2022-04-26
  • 1 回答
  • 0 關注
  • 137 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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