Опубликован: 22.06.2005 | Уровень: для всех | Доступ: платный | ВУЗ: Компания IBM
Лекция 5:

Доступ процессов к файлам и каталогам

< Лекция 4 || Лекция 5: 1234 || Лекция 6 >

Сигналы

Чтобы завершить работу фонового процесса с помощью " ^C ", Мефодию пришлось сначала сделать его активным. Это не всегда возможно и не всегда удобно. На самом деле, " ^C " – это не волшебная кнопка-убийца, а предварительно установленный символ (с ascii-кодом 3), при получении которого с терминала Linux передаст активному процессу сигнал 2 (по имени INT, от "interrupt" – "прервать").

Сигнал – это способность процессов обмениваться стандартными короткими сообщениями непосредственно с помощью системы. Сообщение-сигнал не содержит никакой информации, кроме номера сигнала (для удобства вместо номера можно использовать предопределенное системой имя). Для того чтобы передать сигнал, процессу достаточно задействовать системный вызов kill(), а для того чтобы принять сигнал, не нужно ничего. Если процессу необходимо как-то по-особенному реагировать на сигнал, он может зарегистрировать обработчик, а если обработчика нет, за него отреагирует система. Как правило, это приводит к немедленному завершению процесса, получившего сигнал. Обработчик сигнала запускается асинхронно, немедленно после получения сигнала, что бы процесс в это время ни делал.

Сигнал - короткое сообщение, посылаемое системой или процессом другому процессу. Обрабатывается асинхронно специальной подпрограммой-обработчиком. Если процесс не обрабатывает сигнал самостоятельно, это делает система.

Два сигнала – 9 ( KILL ) и 19 ( STOP ) – всегда обрабатывает система. Первый из них нужен для того, чтобы убить процесс наверняка (отсюда и название). Сигнал STOP приостанавливает процесс: в таком состоянии процесс не удаляется из таблицы процессов, но и не выполняется до тех пор, пока не получит сигнал 18 ( CONT ) – после чего продолжит работу. В Linux сигнал STOP можно передать активному процессу с помощью управляющего символа " ^Z ":

[methody@localhost methody]$ sh loop
^Z
 [1]+ Stopped 	sh loop
[methody@localhost methody]$ bg
 [1]+ sh loop &
[methody@localhost methody]$ fg
 sh loop
^C
[methody@localhost methody]$
5.6. Перевод процесса в фон с помощью "^Z" и bg

Мефодий сначала запустил вечный цикл в качестве активного процесса, затем передал ему сигнал STOP с помощью " ^Z ", после чего дал команду bg ( b ack g round), запускающую в фоне последний остановленный процесс. Затем он снова перевел этот процесс в активный режим, и, наконец, убил его.

Передавать сигналы из командной строки можно любым процессам с помощью команды kill -сигнал PID или просто kill PID, которая передает сигнал 15 ( TERM ):

[methody@localhost methody]$ sh
sh-2.05b$ sh loop & bash loop &
 [1] 3652
 [2] 3653
sh-2.05b$ ps -fH
 UID 		PID	PPID	C	STIME	TTY	TIME		CMD
 methody	3590	1850	0	13:58	tty3	00:00:00	-bash
 methody 	3634	3590	87	14:03	tty3	00:14:18	sh loop
 methody 	3651	3590	0	14:19	tty3	00:00:00	sh
 methody	3652	3651	34	14:19	tty3	00:00:01	sh loop
 methody 	3653	3651	35	14:19	tty3	00:00:01	bash loop
 methody 	3654	3651	0	14:19	tty3	00:00:00	ps -fH
5.7. Запуск множества фоновых процессов

Мефодий решил запустить несколько процессов, а потом выборочно поубивать их. Для этого он, вдобавок к уже висящему в фоне sh loop, запустил в качестве активного процесса новый командный интерпретатор, sh (при этом изменилось приглашение командной строки ). Из этого sh он запустил в фоне еще один sh loop и новый bash loop. Сделал он это одной командной строкой (при этом команды разделяются символом " & ", т. е. "И"; выходит, что запускается и та, и другая команда). В ps он использовал новый ключ – " -H " (" H ierarchy", "иерархия"), который добавляет в выдачу ps отступы, показывающие отношения "родитель–потомок" между процессами:

sh-2.05b$ kill 3634
 [1]+ Terminated       sh loop
sh-2.05b$ ps -fH
 UID 		PID	PPID	C	STIME	TTY	TIME		CMD
 methody 	3590	1850	0	13:58	tty3	00:00:00	-bash
 methody	3651	3590	0	14:19	tty3	00:00:00	sh
 methody	3652	3651	34	14:19	tty3	00:01:10	sh loop
 methody	3653	3651	34	14:19	tty3	00:01:10	bash loop
 methody	3658	3651	0	14:23	tty3	00:00:00	ps -fH
5.8. Принудительное завершение процесса с помощью kill

Мефодий принялся убивать! Для начала он остановил работу давно запущенного sh, выполнявшего сценарий с вечным циклом ( PID 3634 ). Как видно из предыдущего примера, этот процесс за 16 минут работы системы "съел" не менее 14 минут процессорного времени, и конечно, ничего полезного не сделал. Сигнал о том, что процесс-потомок "умер", дошел до обработчика в стартовом bash ( PID 3590 ), и на терминал было выведено сообщение " [1]+ Terminated sh loop ", после чего стартовый bash продолжил ждать завершения активного процессаsh ( PID 3651).

sh-2.05b$ exit
[methody@localhost methody]$ ps -fH
 UID 		PID	PPID	C	STIME	TTY	TIME		CMD
 methody	3590	1850	0	15:17	tty3	00:00:00	-bash
 methody	3663	3590	0	15:23	tty3	00:00:00	ps -fH
 methody	3652	1	42	15:22	tty3	00:00:38	bash loop
 methody	3653	1	42	15:22	tty3	00:00:40	sh loop
[methody@localhost methody]$ kill -HUP 3652 3653
[methody@localhost methody]$ ps
  PID	TTY 	TIME		CMD
 3590	tty3 	00:00:00	bash
 3664	tty3 	00:00:00	ps
5.9. Завершение процесса естественным путем с помощью сигнала "Hang Up"

Ждать ему оставалось недолго. Этот sh завершился естественным путем, от команды exit, оставив после себя двух "детей-сирот" ( PID 3652 и 3653 ), которые тотчас же усыновил "отец всех процессов " – init ( PID 1 ). Когда Мефодий расправился и с ними – с помощью сигнала 1 ( HUP, то есть " H ang UP ", "повесить"2Имя этого сигнала происходит не от казни через повешение, а от повешенной телефонной трубки. ) – некому было даже сообщить об их кончине (если бы процесс-родитель был жив, на связанный с ним терминал вывелось бы что-нибудь вроде " [1]+ Hangup sh loop ").

< Лекция 4 || Лекция 5: 1234 || Лекция 6 >
Тимур Булатов
Тимур Булатов

С момента выхода курса прошло достаточно много времени, и хотелось бы понимать, насколько курс является актуальным на сегодняшний день.

дмитрий шремзер
дмитрий шремзер

В поле PPID (" p arent p rocess id entificator") указан идентификатор родительского процесса, т. е. процессапородившего данный. Для ps это – bash, а для bash, очевидно, login

А что тогда находится в поле CMD?

Гузель Фахретдинова
Гузель Фахретдинова
Россия
Алексей Маряскин
Алексей Маряскин
Россия