Чтобы ответить на этот вопрос, вы должны понять, как сигналы отправляются процессу и как процесс существует в ядре.
Каждый процесс представлен 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?