在繁忙的循环中休眠 goroutine

Sleep in goroutine with busy loop

我在 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 就足够了吗?

使用对 time.Sleep 的调用绝不是协调并发进程的正确选择,最好尽可能依赖同步原语和运行时来协调并发。

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

如果您无法避免轮询某个事件,那么您可以通过使用 time.Ticker 使轮询间隔更加一致来稍微改进一下。

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