Способ go
инициирования отмены задачи / службы заключается в использовании пакета context.Context .
Поэтому, если вы хотите, чтобы обработчик сигнала инициировал закрытиеcontext.Context
:
func registerSigHandler() context.Context {
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
rootCtx := context.Background()
taskCtx, cancelFn := context.WithCancel(rootCtx)
go func() {
sig := <-sigCh
log.Println("received signal:", sig)
// let sub-task know to wrap up: cancel taskCtx
cancelFn()
}()
return taskCtx
}
задачи, а затем передать возвращенное taskCtx
вашему рабочему заданию для прослушивания.
select {
case <-taskCtx.Done():
// context was canceled
default: // poll - rather than block in this example
}
Playground source-code .
Выход:
2019/03/10 19:18:51 Worker PID: 33186
2019/03/10 19:18:51 Will terminate on these signals: interrupt terminated
2019/03/10 19:18:51 2019-03-10 19:18:51.018962 -0400 EDT m=+0.001727305
2019/03/10 19:18:52 2019-03-10 19:18:52.022782 -0400 EDT m=+1.005517010
2019/03/10 19:18:53 2019-03-10 19:18:53.019925 -0400 EDT m=+2.002630457
$ kill -INT 33186
2019/03/10 19:18:53 received signal: interrupt
2019/03/10 19:18:53 task context terminated reason: context canceled
2019/03/10 19:18:53 wrapping up task...
2019/03/10 19:18:53 workerTask() exited cleanly
2019/03/10 19:18:53 main exited cleanly
РЕДАКТИРОВАТЬ:
Я проверил это на Windows 10
и очистка запускается, когдаCtrl-C выдается из той же консоли.Не уверен, как отправлять сигналы извне в Windows - что может быть оригинальной проблемой ОП.Использование скажем killtask /F /PID 33186
действительно убило бы процесс без запуска какого-либо обработчика сигнала.