在goroutine中使用忙循环睡眠

在goroutine中使用忙循环睡眠,go,sleep,goroutine,Go,Sleep,Goroutine,我在goroutine中有一个switch语句,它处理音频的播放状态。switch语句如下所示(由通道控制) PlaybackLoop: //轮询播放状态并更新当前歌曲 挑选{ case使用调用time.Sleep从来都不是协调并发进程的正确选项,最好尽可能依赖同步原语和运行时来协调并发 在这种情况下,您似乎正在轮询一个事件,而睡眠是为了防止您运行一个繁忙的循环,这只会浪费cpu,并可能导致其他goroutine/threads的cpu不足 如果您无法避免对事件进行轮询,则可以使用time.Ti

我在goroutine中有一个switch语句,它处理音频的播放状态。switch语句如下所示(由通道控制)

PlaybackLoop:
//轮询播放状态并更新当前歌曲
挑选{

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

在这种情况下,您似乎正在轮询一个事件,而睡眠是为了防止您运行一个繁忙的循环,这只会浪费cpu,并可能导致其他goroutine/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()
        }
    }
ticker:=time.NewTicker(pollInterval)
延迟停止
回放循环:
为了{
挑选{

案例否,对于任何并发性问题,睡眠几乎从来都不是正确的答案。为什么在交换机中需要一个
默认值
案例?您不能只等待一个接收吗?否,因为switch语句上方的播放检查例如在前一首歌曲结束时播放下一首歌曲,睡眠应该在该检查上减少at表示您正在轮询一个事件,而不是依赖于并发原语。如果确实没有办法轮询,那么是的,您不想创建一个繁忙的循环,您应该稍微延迟轮询。在这种情况下,我宁愿使用
time.Ticker
而不是默认情况下的Sleep。这肯定应该使用
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()
        }
    }