去&#-chan开销

时间:2015-10-29 11:48:48

标签: go

我一直在努力了解Go中的频道。但有一件事让我很奇怪。你打电话时会发生什么,

For {
  select {
    case <-chan:
  }
}

它是否每次都检查chan以进行更新迭代?如何与普通的case i = int:case atomic.LoadUint64() = uint64:表现进行比较?

2 个答案:

答案 0 :(得分:3)

  

The Go Programming Language Specification

     

Select statements

     

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

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

  

对于语句中的所有情况,接收的通道操作数   操作以及发送的通道和右侧表达式   语句在输入时按源顺序精确评估一次   “选择”声明。

答案 1 :(得分:1)

通道的实现不是由语言规范定义的(并且永远不会定义),因此特定的实现可以在符合规范的情况下随意执行。< / em>的

另一方面,访问通道的行为类似于访问互斥锁,因此我在内部相信Go安排在适当的资源上使用系统提供的阻止方法。想想Windows上的WaitForMultipleObjects(),Linux上的futex等等。

换句话说,虽然for { select { case <-chan: ... } }构造在那些case标签中的对象上看起来像忙等待,但实际上它不是:编译器利用系统&# 39;当其中一些资源可用时,会通知Go运行时调度程序。