亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

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

同時選擇發送和接收通道

同時選擇發送和接收通道

Go
呼啦一陣風 2021-09-13 10:56:44
假設我有一個緩沖發送和非緩沖接收通道:s := make(chan<- int, 5)r := make(<-chan int)是否可以select同時r選擇它們,以便在有內容閱讀時s將其選中,如果未滿則將被選中?與此等效的東西,但不使用 100% CPU:for {    if len(s) < cap(s) {        // Send something    }    if len(r) > 0 {        // Receive something    }}請注意,我想在發送時決定要發送的內容,而不是更早。編輯這個問題基本上相當于“我可以阻塞直到一個通道準備好發送,而不發送任何東西嗎?”
查看完整描述

3 回答

?
ABOUTYOU

TA貢獻1812條經驗 獲得超5個贊

您可以這樣做,select但由于要發送的值只評估一次,如果兩個通道都沒有準備好,要發送的值將在可以發送時過時。


因此,添加一個default案例,如果沒有任何通道準備好,您將在其中“睡眠”一點,然后再試一次(計算/獲取更新的新值以發送)。通過休眠,您不會消耗 CPU 資源:


s := make(chan<- int, 5)

r := make(<-chan int)


for {

    v := valueToSend() // Evaluated each time we try to send

    select {

    case s <- v:

        fmt.Println("Sent value:", v)

    case vr := <-r:

        fmt.Println("Received:", vr)

    default: // If none are ready currently, we end up here

        time.Sleep(time.Millisecond * 1)

    }

}

請注意,檢查通道的長度或容量然后發送/接收不被認為是一個好的解決方案,因為在檢查其長度/上限和您嘗試發送/接收之間,通道可能未準備好,如下圖所示:


if len(r) > 0 {

    // r is ready to receive


    // Optional other code here,

    // meanwhile another goroutine might receive the value from r!


    r <-  // If other goroutine received from r, this will block!

}


查看完整回答
反對 回復 2021-09-13
?
慕標5832272

TA貢獻1966條經驗 獲得超4個贊

這是一個簡單的選擇:


select {

case s <- n:

    // Successful send.

case n := <- r:

    // Successful receive. Do something with n.

}


查看完整回答
反對 回復 2021-09-13
  • 3 回答
  • 0 關注
  • 194 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號