Почему программы Unix не могут иметь сигналы со значимыми именами, определенными для программ (вместо USR1 и т.д.)?
Многие программы Unix принимают сигналы типа USR1
и USR2
. Например, чтобы обновить исполняемый файл для Nginx "на лету", вы отправляете kill -USR2
.
Я понимаю, что USR1
является "определяемым пользователем" сигналом, что означает, что тот, кто создал программу, может использовать его для обозначения "выключить" или "выгрузить ваши журналы" или "распечатать foo тысячу раз" или что-то еще. Но я не понимаю, почему они должны использовать это произвольное имя. Почему бы не kill -UPGRADE
, или kill -GRACEFUL_SHUTDOWN
? Имеет ли Unix только определенные сигналы?
Пока мы это делаем, Nginx также использует следующие сигналы (см. документация):
- TERM, INT: быстрое отключение
- QUIT: изящное завершение работы
- HUP:
- Конфигурация перезагрузки
- Запустите новые рабочие процессы с новой конфигурацией
- Изящное завершение работы старых рабочих процессов
- USR1: откройте файлы журнала
- USR2: обновление исполняемых на лету
- WINCH: изящное завершение рабочих процессов
HUP? Winch? Какая причина этих имен? Где я могу узнать больше об этом?
Ответы
Ответ 1
Сигналы, доступные в ОС, определяются ОС (обычно после POSIX) - они не являются "строками", а целыми константами со стандартными именами. USR1
и USR2
- это два сигнала, которые не имеют конкретного значения, предназначенные для любого произвольного использования, которое хочет разработчик.
На вашей машине linux прочитайте man 7 signal
для обзора обработки сигналов и сигналов.
Вы можете переопределить значение других сигналов, если вы готовы работать с ОС, выдавая эти сигналы в ответ на события. Вы можете, например, make HUP
означает "перезагрузить конфигурацию" - если вы либо уверены, что процесс никогда не получит зависания (потеря терминала), либо вы готовы обрабатывать случаи, когда ОС, а не пользователь, посылает сигнал HUP.
Ответ 2
HUP
не подходит для "зависания". Этот сигнал отправляется процессу, если его управляющий терминал достигает конца файла. В прежние времена управляющие терминалы обычно подключались к последовательным портам, возможно, через модемную линию по телефонной линии. Если телефонное соединение было повёрнуто, локальный модем снизит линию Carrier Detect, что приведет к отправке отчета о завершении файла ядра и передаваемого сигнала SIGHUP
.
WINCH
не подходит для "изменения окна". Он отправляется процессу, если его управляющий терминал изменяет размер. По понятным причинам терминалы, которые могут изменять размер, обычно представляют собой псевдотерминалы, которые в конечном счете представлены терминальным эмулятором, работающим в среде окон (например, xterm
).
Ответ 3
Попробуйте kill -l
и найдите ответ самостоятельно:
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
Ответ 4
Поскольку имена сигналов стандартизируются (POSIX). Вы можете написать свой собственный исполняемый файл kill-типа, чтобы взять -UPGRADE
, если хотите, и доставить сигнал USR1
, но стандартный kill
, который поставляется с UNIX, не узнает его.
В качестве альтернативы вы можете создать псевдоним, функцию или оболочку script для выполнения перевода для вас, например, с помощью псевдонима bash
:
alias upgrade='kill -USR1'
Файл заголовка signal.h
сопоставляет имена сигналов с их фактическими значениями, зависящими от реализации.
В терминах WINCH
я считаю это немного мерзостью. Это сигнал, который доставляется приложениям при изменении размера окна (особенно когда изменяется окно их управляющего терминала).
Использование этого для изящного закрытия рабочих потоков не является хорошей идеей, если вы не можете гарантировать, что процесс никогда не будет работать в терминале. Я знаю, что был бы очень миф, если бы я запускал приложение, и он решил отменить всю работу в полете только потому, что я максимизировал окно: -)
Ответ 5
На платформах, совместимых с POSIX, SIGUSR1
и SIGUSR2
- это сигналы, посылаемые процессу для указания пользовательских условий. Символьные константы для них определены в файле заголовка signal.h
. Символические имена сигналов используются, поскольку номера сигналов могут различаться на разных платформах.
SIG
является общим префиксом для имен сигналов. USR
является аббревиатурой для пользовательских.
Ответ 6
Имена сигналов начинаются с более ранних времен, чем Posix.
Я хочу поговорить о SIG ** IOT **. В то время, когда использовались мейнфреймы DEC PDP, используемый процессор имел специальную инструкцию IOT (Trap I/O Trap), которая часто использовалась для кратковременного сбоя системы - как правило, для ее перезагрузки (в серверах реального времени). Этот метод использовал все ядро вместе с драйверами устройств и привилегированные процессы (написанные на ассемблере). Даже сегодня есть процессоры, которые все еще имеют эту инструкцию IOT.
Итак, когда ядро испытывает выполнение инструкции IOT в непривилегированном домене, он вызывает SIGIOT для затронутого процесса.