在Go语言中,可以使用带有超时模式的通道来跳出循环。

huangapple go评论97阅读模式
英文:

golang use channel with time out pattern to jump out of loop

问题

学习了来自《Go并发模式》中的超时模式后,我尝试检查一个通道并跳出for循环。

循环:

for {
    // 在for循环中重复执行某些操作

    // 检查exitMessage以确定是否跳出循环
    select {
        case <-exitMessage:
            break Loop
        case <-time.After(1 * time.Millisecond):
    }
}

超时机制避免了select在读取通道时被阻塞。问题是,在Windows XP机器上,这个延迟比1毫秒要长得多(参考时间延迟不准确的问题),这会显著减慢for循环的速度。

一个折中的解决方案是创建另一个goroutine(我知道它很廉价)来监听exitMessage

exitFlag := 0

// 另一个goroutine来检查exitMessage
go func(in chan int) {
    exitFlag = <-in
}(exitMessage)

for exitFlag == 0 {
    // 在for循环中重复执行某些操作
}

是否有更好的模式来中断Go中的for循环?

英文:

Learning from go time out pattern go concurrency patterns, I try to check a channel and to break out of a for loop

Loop: 
   for {
      //do something repeatedly very fast in the for loop

     //check exitMessage to see whether to break out or not
      select {
          case &lt;- exitMessage:
               break Loop
          case &lt;- time.After(1 * time.Millisecond):
       }
   }  

The time-out avoids select gets stuck reading from a channel. The problem is that on a Windows XP machine, that delay is much longer than 1 millisecond (per time delay inaccuracy problem) which slows down the for-loop significantly.

A hacked-up solution is to get another goroutine (I know it's cheap) to listen for the exitMessage

exitFlag := 0

//another goroutine to check exitMessage
go fun(in chan int){
    exitFlag = &lt;-in
}(exitMessage)


for exitFlag == 0 {
       //do something repeatedly very fast in the for loop

       
 }

Is there a better pattern to interrupt a for-loop in go?

答案1

得分: 12

使用带有默认子句的选择语句如何?如果通道无法接收,将执行默认子句。

循环:
   for {
      select {
          // 检查 exitMessage 是否为真,以确定是否跳出循环
          case <- exitMessage:
               break Loop
          // 在 for 循环中重复执行某些操作
          default:
               // 处理逻辑
       }
   }  
英文:

How about using a select statement with a default clause which will execute if the channel can't receive?

Loop:
   for {
      select {
          //check exitMessage to see whether to break out or not
          case &lt;- exitMessage:
               break Loop
          //do something repeatedly very fast in the for loop
          default:
               // stuff
       }
   }  

huangapple
  • 本文由 发表于 2014年2月12日 00:45:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/21707845.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定