Go语言 为什么我的自定义“等待频道超时”不起作用,如何使它起作用?

axr492tv  于 2022-12-31  发布在  Go
关注(0)|答案(1)|浏览(194)

我正在尝试创建我自己的自定义“Channel Timeout”。更准确地说,是它里面的time.After函数。换句话说,我正在尝试实现这个:

select {
case v := <-c:
    fmt.Println("Value v: ", v)
case <-time.After(1 * time.Second):
    fmt.Println("Timeout")
}

但不幸的是我遇到了一个问题。
我的实现是:

func waitFun(wait int) chan int {
    time.Sleep(time.Duration(wait) * time.Second)

    c := make(chan int)
    c <- wait

    return c
}

func main() {
    c := make(chan int)
    go func() {
        time.Sleep(3 * time.Second)
        c <- 10
    }()

    select {
    case v := <-c:
        fmt.Println("Value v: ", v)
    case <-waitFun(1):
        fmt.Println("Timeout")
    }

    time.Sleep(4 * time.Second)
}

由于某种原因,此操作不起作用。错误为:all goroutines are asleep - deadlock!我知道在某种程度上所有的goroutine(main和一个匿名函数)将进入睡眠状态,但这是错误的原因还是其他原因?我的意思是,它不是“无限睡眠”或“无限等待某个东西”,所以它不是死锁,对吗?此外,使用time.After也会睡眠goroutine,我需要做什么修改才能让程序正常工作?

nmpmafwu

nmpmafwu1#

select语句在运行时将评估所有情况,因此此代码实际上将等待waitFun返回,然后才开始侦听任何通道。您必须更改waitFun以立即返回通道:

func waitFun(wait int) chan int {
    c := make(chan int)
    go func() {
       time.Sleep(time.Duration(wait) * time.Second)
       c <- wait
    }()
    return c
}

相关问题