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

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

在這個(gè) golang 程序中如何避免死鎖?

在這個(gè) golang 程序中如何避免死鎖?

Go
牛魔王的故事 2022-01-10 16:25:00
這是我的程序正在產(chǎn)生死鎖,我該如何避免它以及處理這種情況的推薦模式是什么。問題是超時(shí)后如何檢測(cè)到我的頻道上沒有閱讀器?var wg sync.WaitGroupfunc main() {       wg.Add(1)    c := make(chan int)    go readFromChannel(c, time.After(time.Duration(2)*time.Second))    time.Sleep(time.Duration(5) * time.Second)    c <- 10    wg.Wait()}func readFromChannel(c chan int, ti <-chan time.Time) {    select {    case x := <-c:        fmt.Println("Read", x)    case <-ti:        fmt.Println("TIMED OUT")    }    wg.Done()}
查看完整描述

3 回答

?
繁星淼淼

TA貢獻(xiàn)1775條經(jīng)驗(yàn) 獲得超11個(gè)贊

所以,讓我們看看你的源代碼中到底發(fā)生了什么。你有兩個(gè)goroutine(不止兩個(gè),但我們將專注于顯式的),main和readFromChannel.


讓我們看看有什么readFromChannel作用:


if channel `c` is not empty before `ti` has expired, print its contents and return, after signalling its completion to wait group.

if `ti` has expired before `c` is not empty, print "TIMED OUT" and return, after signalling its completion to wait group.

現(xiàn)在主要:


adds to waitgroup 

make a channel `c`

start a goroutine `readFromChannel`

sleep for 5 seconds

send 10 to channel `c`

call wait for waitgroup

現(xiàn)在,讓我們同時(shí)執(zhí)行您的代碼的執(zhí)行流程(您的代碼可能/可能不會(huì)每次都按此順序執(zhí)行,請(qǐng)記住這一點(diǎn))


1) wg.Add(1)

2) c := make(chan int)

3) go readFromChannel(c, time.After(time.Duration(2)*time.Second))

#timer ti starts#

4) time.Sleep(time.Duration(5) * time.Second)

#MAIN Goroutine begins sleep

#timer ti expires#

5) case <-ti:

6) fmt.Println("TIMED OUT")

7) wg.Done()

# readFromChannel Goroutine returns #

#MAIN Goroutine exits sleep#

8) c<-10

9) ......#DEADLOCK#

現(xiàn)在你可以猜到為什么會(huì)出現(xiàn)死鎖。在進(jìn)行中,非緩沖通道將阻塞,直到通道的另一端發(fā)生某些事情,無論您是發(fā)送還是接收。所以c <- 10會(huì)阻塞,直到從 的另一端讀取某些內(nèi)容c,但是您為此擁有的 goroutine 已在 2 秒前從圖片中刪除。因此,c永遠(yuǎn)阻塞,并且由于main是最后一個(gè) goroutine,你會(huì)得到一個(gè)死鎖。


如何預(yù)防?使用頻道時(shí),請(qǐng)確保receive在頻道的另一端始終有一個(gè)send.


在這種情況下使用緩沖通道可以作為一種快速修復(fù),但可能會(huì)在更大的存儲(chǔ)庫(kù)中引發(fā)潛在的陷阱。例如,假設(shè)您c隨后寫入了更多數(shù)據(jù)并go readFromChannel(c, time.After(time.Duration(2)*time.Second))再次運(yùn)行。你可能會(huì)看到:


Read D1

Read D2

或者


TIMED OUT

Read D1

完全基于機(jī)會(huì)。這可能不是您想要的行為。


以下是我解決死鎖的方法:


func main() {

    wg.Add(1)

    c := make(chan int)

    go readFromChannel(c, time.After(time.Duration(2)*time.Second))

    time.Sleep(time.Duration(5) * time.Second)

    c <- 10

    wg.Wait()

}


func readFromChannel(c chan int, ti <-chan time.Time) {

        // the forloop will run forever

    loop: // **

    for {

        select {

            case x := <-c:

                    fmt.Println("Read", x)

                    break loop // breaks out of the for loop and the select **

            case <-ti:

                    fmt.Println("TIMED OUT")

            }

    }

    wg.Done()


查看完整回答
反對(duì) 回復(fù) 2022-01-10
?
慕桂英546537

TA貢獻(xiàn)1848條經(jīng)驗(yàn) 獲得超10個(gè)贊

你有一個(gè)無緩沖的頻道。根據(jù)文檔

如果通道沒有緩沖,發(fā)送方會(huì)阻塞,直到接收方收到該值。如果通道有緩沖區(qū),發(fā)送方只會(huì)阻塞,直到值被復(fù)制到緩沖區(qū)

通過將通道更改為緩沖,我們可以避免死鎖。

c := make(chan int, 10) // holds 10 ints

我還建議閱讀https://golang.org/doc/effective_go.html#channels,里面有一些與頻道相關(guān)的好東西。


查看完整回答
反對(duì) 回復(fù) 2022-01-10
?
守候你守候我

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超10個(gè)贊

這是一個(gè)較老的問題,但我自己正在深入學(xué)習(xí)渠道并在這里找到了這個(gè)。


我認(rèn)為您只需要在完成發(fā)送后關(guān)閉頻道嗎?


代碼:


func main() {

    wg.Add(1)

    c := make(chan int)

    go readFromChannel(c, time.After(time.Duration(2)*time.Second))

    time.Sleep(time.Duration(5) * time.Second)

    c <- 10

    close(c) // <- CLOSE IT HERE

    wg.Wait()

}


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

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號(hào)

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