Go 程序即使在通过 short time.Duration 之后也会永远休眠

Go program sleeps forever even after passing short time.Duration

我正在尝试在 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:
        }
    }
}

我预计它只是 returns 在打印日志消息并返回之后。

谢谢!

这段代码有很多问题,主要是使用 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