golang select语句中的case与default的优先级

时间:2017-08-09 01:10:23

标签: go

我有一个运行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
  }
}()

这是实现此目的的有效方法吗?我最关心的是所选择的select的分支可能是非确定性的,因此即使其中一个default s,也可以选择case准备好了。这可能吗?是否有任何文档表明匹配的case保证优先于default。关注的是上面的for循环可能会在done关闭后循环多次和/或报告成功,即使发生了超时。

1 个答案:

答案 0 :(得分:7)

  

The Go Programming Language Specification

     

Select statements

     

执行“select”语句分几步进行:

     
      
  1. 对于语句中的所有情况,接收操作的通道操作数以及发送的通道和右侧表达式   语句在输入时按源顺序精确评估一次   “选择”声明。结果是一组要接收的通道   from或send to,以及要发送的相应值。任何一方   无论哪个(如果有的话)都会发生评估中的影响   选择通信操作以继续。表达方式   带有短变量声明的RecvStmt的左侧或   作业尚未评估。
  2.   
  3. 如果一个或多个通信可以继续,则可以通过统一的伪随机选择来选择可以继续的单个通信。   否则,如果存在默认情况,则选择该情况。如果有   没有默认情况,“select”语句会阻塞至少一个   通讯可以继续。
  4.   
  5. 除非所选案例是默认情况,否则将执行相应的通信操作。
  6.   
  7. 如果所选案例是具有短变量声明或赋值的RecvStmt,则左侧表达式为   评估并分配收到的值(或值)。
  8.   
  9. 执行所选案例的陈述清单。
  10.   
  

“我最关心的是选择的分支   选择可能是非确定性的,因此可以选择默认值   如果其中一个案件准备就绪这可能吗?“

没有。请参阅select规范的第2步。