tl; dr , если сигнал может быть обработан средой выполнения go в любое время, как мы можем безопасно использовать signal.Ignore
, чтобы игнорировать SIGINT так, чтобы не было гонки между временем по умолчанию обработчик сигнала установлен, и когда наша инструкция внутри main()
запускает
go документы для pkg / signal заявляет это о поведении сигналов по умолчанию
Сигнал SIGHUP, SIGINT или SIGTERM вызывает выход из программы.
Итак, запишите двоичный файл golang, который вращает процессор, нажмите Ctrl + c, чтобы отправьте SIGINT, и программа закроется.
Теперь, скажем, вы хотите переписать это поведение. Один из способов сделать это - проигнорировать сигнал с помощью signal.Ignore(syscall.SIGINT)
Но теперь рассмотрим следующий
package main
import (
"fmt"
"os/signal"
"syscall"
"time"
)
func main() {
fmt.Println("Looping, SIGINT will have default behavior")
for start := time.Now(); time.Now().Before(start.Add(time.Second * 5)); {
}
signal.Ignore(syscall.SIGINT)
fmt.Println("OK")
for start := time.Now(); time.Now().Before(start.Add(time.Second * 5)); {
}
}
Здесь у нас есть простой двоичный файл golang, который зацикливается на 5 секунд. Это занято oop, поэтому мы знаем, что не участвуем в совместной многозадачности, уступая время в потоке ОС. Затем он регистрируется для игнорирования SIGINT.
Если вы попробуете это, вы заметите, что если вы введете Ctrl + c в течение первых 5 секунд, программа закроется. Кажется, это имеет смысл - мы получаем стандартное поведение обработки сигналов golang во время выполнения, потому что мы еще не переопределили его с помощью нашего вызова signal.Ignore
.
Теперь, возможно, мы могли бы решить эту проблему, переместив signal.Ignore
- это первое, что нужно сделать в main (), однако, эта программа доказывает, что среда выполнения go не дает никаких гарантий того, что обработчик сигналов по умолчанию не запустится до завершения выполнения вашего синхронного кода в main ().
Даже если вы переместите его, мы, похоже, находимся в гонке между
- Точкой, в которой среда выполнения go регистрирует свои обработчики сигналов по умолчанию, и
- Самая ранняя точка, в которой наш код может выполняться (первая (или вторая, если вам нужен канал) инструкция в основном)
Я не могу найти документацию по этому вопросу. Какие гарантии дает время выполнения go, чтобы я чувствовал себя абсолютно уверенным, что сигнал не может прийти между этапами 1 и 2?