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

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

帶有通道和等待組的 Golang 選擇語句

帶有通道和等待組的 Golang 選擇語句

Go
開滿天機 2022-06-01 09:55:33
在使用 Golang 進行實驗時,我創建了一個帶有 select 語句的函數,它監聽兩個通道。我的問題是代碼似乎表現得不確定——有時它會恐慌,有時它會成功完成。我的期望是這段代碼應該總是恐慌。它應該首先收到錯誤,因為它應該在 waitGroup 完成之前調度,因此在成功通道被推送到之前。package mainimport (    "errors"    "fmt"    "sync")func main() {    errs := make(chan error, 1)    success := make(chan bool, 1)    doSomething(success, errs)    select {    case err := <-errs:        fmt.Println("error", err)        panic(err)    case <-success:        fmt.Println("success")    }    fmt.Println("finished successfully")}func doSomething(success chan bool, errs chan error) {    var wg sync.WaitGroup    wg.Add(1)    go func() {        defer wg.Done()        err := errors.New("Some error")        errs <- err    }()    wg.Wait()    success <- true}
查看完整描述

1 回答

?
互換的青春

TA貢獻1797條經驗 獲得超6個贊

在 select 語句之前,兩個通道都準備好了;因此它將通過統一的偽隨機選擇進行選擇:


讓我們替換doSomething代碼中的函數調用,并將 defer 放在函數的末尾:


package main


import (

    "errors"

    "fmt"

    "sync"

)


func main() {

    errs := make(chan error, 1)

    success := make(chan bool, 1)


    var wg sync.WaitGroup

    wg.Add(1)

    go func() {

        err := errors.New("some error")

        errs <- err

        wg.Done()

    }()


    wg.Wait()

    success <- true


    select {

    case err := <-errs:

        fmt.Println("error", err)

        panic(err)

    case <-success:

        fmt.Println("success")

    }

    fmt.Println("finished successfully")

}

正如你在上面的代碼示例中看到的,主 goroutine在這個時間點wg.Wait()等待,代碼(幾乎)在功能上等于以下代碼,并且兩個通道在此處的 select 語句之前準備好: wg.Done()


package main


import (

    "errors"

    "fmt"

)


func main() {

    errs := make(chan error, 1)

    success := make(chan bool, 1)

    errs <- errors.New("some error")

    success <- true


    select {

    case err := <-errs:

        fmt.Println(err)

    case <-success:

        fmt.Println("success")

    }

}

跑:


$ go run .

some error


$ go run .

success

選擇語句:


如果一個或多個通信可以進行,則通過統一的偽隨機選擇選擇一個可以進行的通信。否則,如果存在默認情況,則選擇該情況。如果沒有默認情況,“select”語句會阻塞,直到至少有一個通信可以繼續。


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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