【问题标题】:Go program sleeps forever even after passing short time.Duration即使经过很短的时间,Go 程序也会永远休眠。持续时间
【发布时间】:2020-01-01 22:40:30
【问题描述】:

我正在尝试在 Go 中构建一些短信号量。虽然当通道接收到信号时,它只是永远休眠。

我尝试过改变睡眠方式和睡眠时间,但它仍然只是永远停止。

这里是我尝试过的表示:

func main() {
    backOffChan := make(chan struct{})
    go func() {
        time.Sleep(2)
        backOffChan <- struct{}{}
    }()
    for {
        select {
        case <-backOffChan:
            d := time.Duration(5 * time.Second)
            log.Println("reconnecting in %s", d)
            select {
            case <-time.After(d):
                log.Println("reconnected after %s", d)
                return
            }
        default:
        }
    }
}

我希望它在打印日志消息并返回后才返回。

谢谢!

【问题讨论】:

    标签: go time channel


    【解决方案1】:

    这段代码有很多问题,主要是使用for/select 的紧密循环可能不允许其他goroutine 在通道上发送。由于default 是空的,而select 只有一个case,所以整个select 是不必要的。以下代码正常工作:

    backOffChan := make(chan struct{})
    go func() {
        time.Sleep(1 * time.Millisecond)
        backOffChan <- struct{}{}
    }()
    for range backOffChan {
        d := time.Duration(10 * time.Millisecond)
        log.Printf("reconnecting in %s", d)
        select {
        case <-time.After(d):
            log.Printf("reconnected after %s", d)
            return
        }
    }
    

    这将等到backOffChan 收到消息,而不会烧死循环。

    (请注意,此代码还解决了使用带有格式指令的 log.Println 的问题 - 这些已更正为 log.Printf)。

    在此处查看实际操作:https://play.golang.org/p/ksAzOq5ekrm

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-13
      • 2020-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多