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