dtftao7249656 2017-08-09 01:10
浏览 77
已采纳

golang select语句中大小写优先与默认优先

I have an application with multiple goroutines that are running for loops, and need a way to signal these for loops to break, and to test whether the timeout case occurred. I was looking into using a shared channel with select statements to accomplish this as follows:

// 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
  }
}()

Is this a valid way to accomplish this? What I'm most concerned about is that the branch of a select that is chosen could be non-deterministic, so that default may be chosen even if one of the cases is ready. Is this possible? Is there any documentation that states that a matching case is guaranteed to have preference over a default. The concern is that the for loop above could loop several times after done is closed and/or report success even though a timeout occurred.

  • 写回答

1条回答 默认 最新

  • duanci3845 2017-08-09 01:18
    关注

    The Go Programming Language Specification

    Select statements

    Execution of a "select" statement proceeds in several steps:

    1. For all the cases in the statement, the channel operands of receive operations and the channel and right-hand-side expressions of send statements are evaluated exactly once, in source order, upon entering the "select" statement. The result is a set of channels to receive from or send to, and the corresponding values to send. Any side effects in that evaluation will occur irrespective of which (if any) communication operation is selected to proceed. Expressions on the left-hand side of a RecvStmt with a short variable declaration or assignment are not yet evaluated.
    2. If one or more of the communications can proceed, a single one that can proceed is chosen via a uniform pseudo-random selection. Otherwise, if there is a default case, that case is chosen. If there is no default case, the "select" statement blocks until at least one of the communications can proceed.
    3. Unless the selected case is the default case, the respective communication operation is executed.
    4. If the selected case is a RecvStmt with a short variable declaration or an assignment, the left-hand side expressions are evaluated and the received value (or values) are assigned.
    5. The statement list of the selected case is executed.

    "What I'm most concerned about is that the branch of a select that is chosen could be non-deterministic, so that default may be chosen even if one of the cases is ready. Is this possible?"

    No. See step 2 of the select specification.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!