我有一个运行for循环的多个goroutine应用程序,需要一种方法来指示这些for循环中断,并测试是否发生了超时情况.我正在考虑使用带select语句的共享通道来完成此操作,如下所示:
// elsewhere in the code, this channel is created, and passed below
done := make(chan struct{})
time.AfterFunc(timeout, func() { close(done) })
...
go func() {
Loop:
for {
select {
case <-done:
break Loop
default:
foo()
time.Sleep(1 * time.Second)
}
}
select {
case <-done:
panic("timed out!")
default:
// ok
}
}()
Run Code Online (Sandbox Code Playgroud)
这是实现这一目标的有效方法吗?我最关心的select是所选择的分支可能是非确定性的,因此default即使其中一个case已经准备就可以选择.这可能吗?是否有任何文档声明匹配case保证优先于a default.关注的是,done即使发生超时,上面的for循环也可以在关闭后循环几次和/或报告成功.
执行"select"语句分几步进行:
- 对于语句中的所有情况,接收操作的通道操作数以及发送语句的通道和右侧表达式在输入"select"语句后按源顺序精确计算一次.结果是一组要接收或发送的通道,以及要发送的相应值.无论选择哪种(如果有的话)通信操作进行,评估中的任何副作用都将发生.尚未评估具有短变量声明或赋值的RecvStmt左侧的表达式.
- 如果一个或多个通信可以继续,则可以通过统一的伪随机选择来选择可以继续的单个通信.否则,如果存在默认情况,则选择该情况.如果没有默认情况,则"select"语句将阻塞,直到至少一个通信可以继续.
- 除非所选择的情况是默认情况,否则执行相应的通信操作.
- 如果所选案例是具有短变量声明或赋值的RecvStmt,则评估左侧表达式并分配接收值(或多个值).
- 执行所选案例的语句列表.
"我最关心的是所选择的选择的分支可能是非确定性的,因此即使其中一个案例已经准备就可以选择默认值.这可能吗?"
不可以.请参阅select规范的第2步.
| 归档时间: |
|
| 查看次数: |
1025 次 |
| 最近记录: |