Чтобы ответить на этот вопрос, вы должны понять, как сигналы отправляются процессу и как процесс существует в ядре.
Каждый процесс представлен task_struct
внутри ядра (определение находится в sched.h
заголовочном файле и начинается здесь ). Эта структура содержит информацию о процессе; например пид. Важная информация находится в строке 1566, где хранится соответствующий сигнал. Это устанавливается, только если сигнал отправляется процессу.
Мертвый процесс или процесс зомби все еще имеет task_struct
. Структура сохраняется до тех пор, пока родительский процесс (естественный или принятый) не будет вызван wait()
после получения, SIGCHLD
чтобы пожинать свой дочерний процесс. Когда сигнал отправляется, signal_struct
устанавливается. В данном случае не имеет значения, является ли сигнал уловимым или нет.
Сигналы оцениваются каждый раз при запуске процесса. Или, если быть точным, перед тем процесс будет работать. Процесс тогда в TASK_RUNNING
состоянии. Ядро выполняет schedule()
процедуру, которая определяет следующий запущенный процесс в соответствии с его алгоритмом планирования. Предполагая, что этот процесс является следующим запущенным процессом, оценивается значение, независимо от signal_struct
того, есть ли ожидающий сигнал для обработки или нет. Если обработчик сигнала определяется вручную (через signal()
или sigaction()
), выполняется зарегистрированная функция, если не выполняется действие по умолчанию для сигнала . Действие по умолчанию зависит от отправляемого сигнала.
Например, SIGSTOP
обработчик сигнала по умолчанию изменит состояние текущего процесса TASK_STOPPED
и затем запустит его, schedule()
чтобы выбрать новый процесс для запуска. Обратите внимание, SIGSTOP
что не может быть перехвачено (как SIGKILL
), поэтому нет возможности зарегистрировать ручной обработчик сигнала. В случае неуловимого сигнала действие по умолчанию всегда будет выполняться.
На ваш вопрос:
Планировщик никогда не определит, что процесс, завершивший работу или остановившийся, TASK_RUNNING
снова будет в состоянии. Таким образом, ядро никогда не будет запускать обработчик сигнала (по умолчанию или определенный) для соответствующего сигнала, какой бы сигнал ни был. Поэтому exit_signal
никогда не будет установлен снова. Сигнал «доставляется» в этот процесс, установив signal_struct
в task_struct
процессе, но ничего не произойдет, потому что процесс никогда не будет работать снова. Код для запуска отсутствует, все, что осталось от процесса, - это структура процесса.
Однако, если родительский процесс wait()
получает свои дочерние элементы , код выхода, который он получает, является тем, когда процесс «изначально» умер. Неважно, есть ли сигнал, ожидающий обработки.
kill
возвращает 0 или 1?