在忙碌的循环中睡在goroutine中

时间:2018-02-08 16:02:34

标签: go sleep goroutine

我在goroutine中有一个switch语句,用于处理音频的播放状态。 switch语句看起来像这样(它由通道控制)

PlaybackLoop:
        // Poll playback status and update current song
        select {
        case <-next:
            if current.next != nil {
                current = current.next
                break PlaybackLoop
            }
        case <-prev:
            if current.prev != nil {
                current = current.prev
            }
            break PlaybackLoop
        case <-done:
            return err
        default:
            time.Sleep(50 * time.Millisecond)

当没有通道有输入时,default情况sleep为50毫秒。我的理由是,我不会不必刷新UI或检查媒体状态等(在switch语句之前PlayBackLoop中发生的事情)。

睡眠以及使goroutine更有效的适当方法? (通过减少对媒体播放器状态的检查?)或者这个假设是完全没有根据的,一个简单的continue就足够了吗?

1 个答案:

答案 0 :(得分:3)

使用对time.Ticker的调用永远不是协调并发进程的正确选择,并且最好依靠同步原语和运行时来尽可能地协调并发。

在这种情况下,您似乎正在轮询一个事件,并且睡眠是为了防止您运行繁忙的循环,这只会浪费CPU并且可能会使CPU的其他goroutine / thread饿死。

如果您无法避免轮询某个事件,那么您可以使用 ticker := time.NewTicker(pollInterval) defer ticker.Stop() PlaybackLoop: for { select { case <-next: if current.next != nil { current = current.next break PlaybackLoop } case <-prev: if current.prev != nil { current = current.prev } break PlaybackLoop case <-done: return err case <-ticker.C: pollForEvent() } } 稍微改善这一点,以使轮询间隔更加一致。

print(set(a))