我正在尝试创建我自己的自定义“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,我需要做什么修改才能让程序正常工作?
1条答案
按热度按时间nmpmafwu1#
select
语句在运行时将评估所有情况,因此此代码实际上将等待waitFun
返回,然后才开始侦听任何通道。您必须更改waitFun
以立即返回通道: