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

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

在監(jiān)視器 goroutine 中遞歸發(fā)送

在監(jiān)視器 goroutine 中遞歸發(fā)送

Go
30秒到達(dá)戰(zhàn)場 2021-12-20 10:11:45
在我正在編寫的一個簡單的計時器調(diào)度程序中,我正在使用監(jiān)視器 goroutine 來同步開始/停止和計時器完成事件。監(jiān)控 goroutine,當(dāng)精簡到基本的時候,看起來像這樣:actions := make(chan func(), 1024)// monitor goroutinego func() {    for a := range actions {        a()    }}()actions <- func() {    actions <- func() {        // causes deadlock when buffer size is reached    }}這很有效,直到發(fā)送一個動作來發(fā)送另一個動作。計劃的操作可能會計劃另一個操作,這會在達(dá)到緩沖區(qū)大小時導(dǎo)致死鎖。有沒有什么干凈的方法來解決這個問題而不訴諸共享狀態(tài)(我在我的特定問題中嘗試過,但很丑陋)?
查看完整描述

1 回答

?
茅侃侃

TA貢獻(xiàn)1842條經(jīng)驗(yàn) 獲得超22個贊

問題源于這樣一個事實(shí),即當(dāng)您的監(jiān)控 goroutine “取出”(接收)一個值(一個函數(shù))并執(zhí)行它(這也發(fā)生在監(jiān)控 goroutine 上)時,它在執(zhí)行過程中會在受監(jiān)控的通道上發(fā)送一個值。


這本身不會導(dǎo)致死鎖,因?yàn)楹瘮?shù)執(zhí)行時( a()),它已經(jīng)從緩沖通道中取出,因此其中至少有一個空閑空間,因此在通道內(nèi)部發(fā)送新值a()可以繼續(xù)進(jìn)行而不會阻塞.


如果還有其他 goroutines 也可能在受監(jiān)控的通道上發(fā)送值,則可能會出現(xiàn)問題,這就是您的情況。


避免死鎖的一種方法是,如果正在執(zhí)行的函數(shù)試圖“放回”(發(fā)送)一個不在同一個 goroutine(即監(jiān)視器 goroutine)中的函數(shù),而是在一個新的 goroutine 中,那么監(jiān)視器 goroutine 不會被阻塞:


actions <- func() {

    // Send new func value in a new goroutine:

    // this will never block the monitor goroutine

    go func() {

        actions <- func() {

            // No deadlock.

        }

    }()

}

通過這樣做,即使緩沖區(qū)actions已滿,monitor goroutine 也不會被阻塞,因?yàn)樵谒厦姘l(fā)送一個值將發(fā)生在一個新的 goroutine 中(可能會被阻塞,直到緩沖區(qū)中有可用空間)。


如果你想避免在發(fā)送一個值時總是產(chǎn)生一個新的 goroutine actions,你可以使用 aselect來首先嘗試發(fā)送它而不產(chǎn)生一個新的 goroutine。僅當(dāng)緩沖區(qū)actions已滿且無法在不阻塞的情況下發(fā)送時,您才應(yīng)生成用于發(fā)送的 goroutine 以避免死鎖,這取決于您的實(shí)際情況可能很少發(fā)生,在這種情況下無論如何避免死鎖是不可避免的:


actions <- func() {

    newfv := func() { /* do something */ }

    // First try to send with select:

    select {

    case actions <- newfv:

        // Success!

    default:

        // Buffer is full, must do it in new goroutine:

        go func() {

            actions <- newfv

        }()

    }

}

如果很多地方都需要這樣做,建議為其創(chuàng)建一個輔助函數(shù):


func safeSend(fv func()) {

    // First try to send with select:

    select {

    case actions <- fv:

        // Success!

    default:

        // Buffer is full, must do it in new goroutine:

        go func() {

            actions <- fv

        }()

    }

}

并使用它:


actions <- func() {

    safeSend(func() {

        // something to do

    })

}


查看完整回答
反對 回復(fù) 2021-12-20
  • 1 回答
  • 0 關(guān)注
  • 160 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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