【发布时间】:2021-11-08 05:20:18
【问题描述】:
我有这两个版本来使用 signal.NotifyContext 对信号实现上下文消除
版本 1 https://play.golang.org/p/rwOnYEgPecE
func main() {
ch := run()
<-ch
}
func run() chan bool {
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)
var done = make(chan bool)
//go func() {
select {
case <-ctx.Done():
fmt.Println("Quitting")
stop()
done <- true
}
//}()
return done
}
版本 2 https://play.golang.org/p/oijbICeSrNT
func main() {
ch := run()
<-ch
}
func run() chan bool {
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)
var done = make(chan bool)
go func() {
select {
case <-ctx.Done():
fmt.Println("Quitting")
stop()
done <- true
}
}()
return done
}
为什么第一个版本打印Quitting行但不退出,而第二个版本打印并正常退出?
【问题讨论】:
-
在操场上,他们都取消并退出。你的操作系统是什么,去版本,去环境?
-
@mh-cbon 为避免平台 CPU 使用率过高,playground 内置了最大执行时间限制,如果程序运行时间过长会自动终止。
-
@colm.anseo 是的,也许,但在这两种情况下都通过
<-context.Done()案例,因此,他们都在退出前取消。 -
第一种情况的问题是
done频道没有缓冲 -
但无论如何,只要关闭它,它就可以了play.golang.org/p/hY7RmVVTfOu