Все процессы в UNIX создаются посредством вызова fork(2) . Запуск на выполнение новых задач осуществляется либо по схеме fork-and-exec, либо с помощью exec(2) . "Прародителем" всех процессов является процесс init(1М) , называемый также распределителем процессов . Если построить граф "родственных отношений" между процессами, то получится дерево, корнем которого является init(1M) . Показанные на рис. 1.6 процессы sched и vhand являются системными и формально не входят в иерархию (они будут рассматриваться в следующих главах).
Рис. 1.6. Типичное "дерево" процессов в UNIX
Сигналы являются способом передачи от одного процесса другому или от ядра операционной системы какому-либо процессу уведомления о возникновении определенного события. Сигналы можно рассматривать как простейшую форму межпроцессного взаимодействия. В то же время сигналы больше напоминают программные прерывания, — средство, с помощью которого нормальное выполнение процесса может быть прервано. Например, если процесс производит деление на 0, ядро посылает ему сигнал SIGFPE
, а при нажатии клавиш прерывания, обычно < Del > или < Ctrl >+< C >, текущему процессу посылается сигнал SIGINT
.
Для отправления сигнала служит команда kill(1) :
kill sig_no pid
где sig_nо
— номер или символическое название сигнала, a pid
— идентификатор процесса, которому посылается сигнал. Администратор системы может посылать сигналы любым процессам, обычный же пользователь может посылать сигналы только процессам, владельцем которых он является (реальный и эффективный идентификаторы процесса должны совпадать с идентификатором пользователя [10] Точнее, с реальным и эффективным идентификаторами процесса, посылающего сигнал. Если вы посылаете сигнал командой kill(1) , работая в shell, то речь идет о командном интерпретаторе.
). Например, чтобы послать процессу, который вы только что запустили в фоновом режиме, сигнал завершения выполнения SIGTERM
, можно воспользоваться командой:
$ long_program &
Запустим программу в фоновом режиме
$ kill $!
По умолчанию команда kill(1) посылает сигнал SIGTERM; переменная $! содержит PID последнего процесса, запущенного в фоновом режиме
При получении сигнала процесс имеет три варианта действий для выбора:
1. Он может игнорировать сигнал. Не следует игнорировать сигналы, вызванные аппаратной частью, например, при делении на 0 или ссылке на недопустимые области памяти, так как дальнейшие результаты в отношении данного процесса непредсказуемы.
2. Процесс может потребовать действия по умолчанию. Как ни печально, обычно это сводится к завершению выполнения процесса.
3. Наконец, процесс может перехватить сигнал и самостоятельно обработать его. Например, перехват сигнала SIGINT
позволит процессу удалить созданные им временные файлы, короче, достойно подготовиться к "смерти". Следует иметь в виду, что сигналы SIGKILL
и SIGSTOP
нельзя ни перехватить, ни игнорировать.
По умолчанию команда kill(1) посылает сигнал с номером 15 — SIGTERM
[11] Соответствие между символьными именами и номерами сигналов может отличаться различных версиях UNIX. Команда kill -l выводит номера сигналов и их имена.
, действие по умолчанию для которого — завершение выполнения процесса, получившего сигнал.
Иногда процесс продолжает существовать и после отправления сигнала SIGTERM
. В этом случае можно применить более жесткое средство — послать процессу сигнал SIGKILL
с номером (9), — поскольку этот сигнал нельзя ни перехватить, ни игнорировать:
$ kill -9 pid
Однако возможны ситуации, когда процесс не исчезает и в этом случае. Это может произойти для следующих процессов:
□ Процессы-зомби. Фактически процесса как такового не существует, осталась лишь запись в системной таблице процессов, поэтому удалить его можно только перезапуском операционной системы. Зомби в небольших количествах не представляют опасности, однако если их много, это может привести к переполнению таблицы процессов.
□ Процессы, ожидающие недоступные ресурсы NFS (Network File System), например, записывающие данные в файл файловой системы удаленного компьютера, отключившегося от сети. Эту ситуацию можно преодолеть, послав процессу сигнал SIGINT
или SIGQUIT
.
Читать дальше