gpt4 book ai didi

带有 channel 和 WaitGroup 的 Golang select 语句

转载 作者:行者123 更新时间:2023-12-01 20:23:30 28 4
gpt4 key购买 nike

尝试使用 Golang,我创建了一个带有 select 语句的函数,用于监听两个 channel 。

我的问题是代码的行为似乎不确定 - 有时它会 panic ,有时它会成功完成。

我的期望是这段代码应该总是 panic 。 它应该首先收到错误,因为它应该在 waitGroup 完成之前被调度,因此在成功 channel 被推送到之前。

package main

import (
"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
}

最佳答案

两个 channel 都准备好了 在 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() 处等待。为 wg.Done() 在这个时间点 该代码(几乎)在功能上等同于以下代码,并且 两个 channel 都准备好了 在选择语句之前:
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_statements :

If one or more of the communications can proceed, a single one that can proceed is chosen via a uniform pseudo-random selection. Otherwise, if there is a default case, that case is chosen. If there is no default case, the "select" statement blocks until at least one of the communications can proceed.

关于带有 channel 和 WaitGroup 的 Golang select 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61271209/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com