如何在Golang中使用’time.After’和’default’?
发布时间:2020-12-16 09:28:12 所属栏目:大数据 来源:网络整理
导读:我试图理解一个简单的Golang例程代码: package mainimport ( "fmt" "time")func sleep(seconds int,endSignal chan- bool) { time.Sleep(time.Duration(seconds) * time.Second) endSignal - true}func main() { endSignal := make(chan bool,1) go sleep(3
我试图理解一个简单的Golang例程代码:
package main import ( "fmt" "time" ) func sleep(seconds int,endSignal chan<- bool) { time.Sleep(time.Duration(seconds) * time.Second) endSignal <- true } func main() { endSignal := make(chan bool,1) go sleep(3,endSignal) var end bool for !end { select { case end = <-endSignal: fmt.Println("The end!") case <-time.After(5 * time.Second): fmt.Println("There's no more time to this. Exiting!") end = true } } } 这很好,但为什么我不能在这个“选择”块中使用简单的默认值?像这样的东西: for !end { select { case end = <-endSignal: fmt.Println("The end.") case <-time.After(4 * time.Second): fmt.Println("There's no more time to this. Exiting!") end = true default: fmt.Println("No end signal received.") } } 它得到这个输出: ? go run goroutines-timeout.go No end signal received! No end signal received! No end signal received! No end signal received! ... The end! 我无法理解为什么. 解决方法
每次执行time.After(4 * time.Second)后,您将创建一个新的计时器通道. select语句无法记住它在上一次迭代中选择的通道.您还采用了异步操作并将其转换为忙循环,从而破坏了select语句的用途.
您只需要对您感兴趣的两个频道进行简单的选择即可.它根本不需要循环. select { case <-endSignal: fmt.Println("The end!") case <-time.After(4 * time.Second): fmt.Println("There's no more time to this. Exiting!") } https://play.golang.org/p/jb4EE8e6cw 如果您真的想要多次轮询,请将计时器置于for循环之外,以便在每次迭代时检查相同的计时器 timeout := time.After(5 * time.Second) pollInt := time.Second for { select { case <-endSignal: fmt.Println("The end!") return case <-timeout: fmt.Println("There's no more time to this. Exiting!") return default: fmt.Println("still waiting") } time.Sleep(pollInt) } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |