<< Предыдущий раздел | /\ Содержание | >> Следующий раздел
Допустим, запустив задачу в фоновом режиме, пользователь выходит из системы, оставляя задачу работать дальше. Хорошо, если это была графическая программа -- у нее почти наверняка будет хотя бы команда "Выход". А если нет, если это какая-либо счетная задача?
В этом случае придется воспользоваться средствами более низкого (системного) уровня -- управлением процессами.
Здесь следует сразу понять разницу. Задача (job) -- это одна или несколько программ (например, конвейер), запущенных из оболочки, которыми можно управлять при помощи команд оболочки jobs, bg, fg и kill. Процесс (process) -- это любая программа, запущенная любым способом (из оболочки; другой программой -- например, из графического меню; самой операционной системой при запуске и т.д.).
Для просмотра списка процессов служит команда "ps". У нее есть довольно много ключей, которые к тому же различаются в BSD и SystemV. Поэтому здесь приведем лишь несколько наиболее часто встречающихся вариантов ее использования. В основном изложение относится к BSD-версии команды ps (в том числе и Linux), эквиваленты для SysV-версии (Solaris, IRIX) приведены отдельно.
Команда ps без параметров выводит список почти всех процессов, принадлежащих запустившему ее пользователю.
bobby:~% ps PID TTY STAT TIME COMMAND 2950 1 S 0:00 -zsh 2971 1 R 0:00 ps bobby:~% _ |
Из всей информации, что выдает ps, для нас пока интересны поля PID и COMMAND.
PID (Process IDentifier) -- это число, уникальное для каждого процесса, которое используется, например, для того, чтобы приостановить или завершить его исполнение. COMMAND -- название программы и ее параметры.
"Почти" -- потому, что в список не включаются процессы "без терминала", т.е. те, которые запущены в фоновом режиме, а окно, из которого это было сделано, потом было закрыто. Чтобы эти процессы также отображались, надо указать ключ "-x"; в поле TTY у них стоит "?".
Ключ "-a" показывает процессы всех пользователей, а не только запустившего ps.
Ключ "-u" выдает более полную информацию о каждом процессе -- потребление процессорного времени, памяти, время запуска.
Ключ "-f" выдает список процессов "со связями", позволяя понять, какой из процессов является чьим "родителем" и чьим "потомком".
Если у пользователя запущено много процессов (например, когда он находится в графической оболочке), то список обычно не помещается на экран. В этом случае надо отправить вывод команды ps команде less. Другой часто используемый прием -- если интересует информация о какой-то конкретной команде, то вывод ps фильтруется через grep. Пример:
bobby:~% ps -x | grep xcalc 3103 ? S N 0:00 xcalc 3107 p9 S 0:00 grep xcalc bobby:~% _ |
|
Команда ps в последних версиях Linux при
указании любых ключей выдает предупреждение типа
На это надо просто не обращать внимания -- просто команда ps сейчас находится в процессе переделки со стандарта BSD на стандарт Unix98, и это предупреждение -- следствие попытки обеспечить совместимость. |
Приблизительные эквиваленты для SystemV (Solaris, IRIX):
Команде kill можно указывать не только номер задания, но и PID. Так, команда "kill 1206" пошлет команду завершения процессу с номером 1206. Стоит напомнить, что при запуске задач оболочка кроме номера задания печатает также PID соответствующего процесса (или процессов, в случае конвейера):
bobby:~% xcalc & [1] 3206 bobby:~% kill 3206 bobby:~% [1] + terminated xcalc bobby:~% _ |
Вообще говоря, "kill" не завершает процесс, а посылает ему сигнал. Процесс же, получив сигнал, может завершиться, а может и предпринять какое-либо другое действие, например, проигнорировать сигнал.
Есть несколько десятков сигналов, каждый из которых имеет свой смысл. Каждый сигнал имеет как имя, так и номер, но, поскольку номера разные в разных Unix'ах, то лучше использовать имена. Чтобы указать kill, какой сигнал послать, надо указать его имя (или номер), предваренное дефисом:
bobby:~% xcalc & [1] 3388 bobby:~% kill -INT 3388 bobby:~% [1] + interrupt xcalc bobby:~% _ |
Вот список самых часто употребляемых сигналов:
Сигнал | Назначение |
---|---|
TERM | TERMinate -- завершить работу. Используется командой kill по умолчанию |
INT | INTerrupt. Посылается при нажатии пользователемCtrl+C |
STOP | "замерзнуть" |
CONT | CONTinue -- "размерзнуть" |
HUP | HangUP -- "повесить трубку". Посылается при выходе пользователя из системы программам, запущенным в этой же сессии |
KILL | "умереть" |
Сигналы TERM, INT, HUP и KILL обычно приводят к завершению работы программы. Разница между ними в том, в каких случаях они посылаются и в том, что одни сигналы программа перехватывает, а другие -- нет.
Сигнал KILL программа перехватить не может, поэтому если она не реагирует больше ни на что, то остается использовать его. Номер KILL во всех Unix'ах -- 9, поэтому его часто указывают по номеру, а не по имени -- "kill -9". Сигнал KILL следует использовать только в крайних случаях, когда ничто другое не помогает. Дело в том, что перехватив, к примеру, сигнал TERM, программа может корректно завершить работу, при надобности сохранив данные в файлы и восстановив правильное состояние терминала, а KILL не дает ей такой возможности.
Вообще говоря, большая часть функций по управлению заданиями реализуется при помощи сигналов. Так, послав программе сигнал STOP, получим тот же эффект, что и при нажатии Ctrl+Z.
В большинстве современных Unix'ов есть возможность послать сигнал процессу, указав его не по номеру, а по имени программы. Для этого служит команда "killall" -- она посылает сигнал всем процессам с указанным именем. Пример:
bobby:~% xcalc& [1] 3478 bobby:~% xcalc& [2] 3479 bobby:~% killall xcalc [1] - terminated xcalc [2] + terminated xcalc bobby:~% _ |
Не стоит ей злоупотреблять -- эта команда мало того, что "убивает" все процессы с таким именем, она пытается "убить" даже процессы с таким именем у других пользователей (чего ей Unix, естественно, не позволяет сделать).
В большинстве современных клонов Unix есть программа, позволяющая оперативно отслеживать, какие процессы запущены в системе и какие из них потребляют больше всего процессорного времени. Эта программа называется "top".
11:33pm up 1 day, 6:20, 12 users, load average: 0.00, 0.00, 0.09 81 processes: 78 sleeping, 3 running, 0 zombie, 0 stopped CPU states: 12.8% user, 2.5% system, 0.3% nice, 85.4% idle Mem: 63136K av, 59612K used, 3524K free, 39772K shrd, 1000K buff Swap: 128516K av, 12552K used, 115964K free 14852K cached PID USER PRI NI SIZE RSS SHARE STAT LIB %CPU %MEM TIME COMMAND 400 root 17 0 26444 19M 1600 R 0 6.9 32.1 137:51 X 1887 ivanov 10 0 4312 4240 3232 R 0 4.0 6.7 117:04 xdos 3505 ivanov 10 0 740 740 564 R 0 2.3 1.1 0:01 top 402 ivanov 1 0 1028 968 560 S 0 0.7 1.5 0:11 fvwm2 2148 ivanov 6 5 2548 2436 644 S N 0 0.3 3.8 0:14 xfte 415 ivanov 0 0 1024 1004 780 S 0 0.1 1.5 0:07 xrus 508 ivanov 1 0 18144 13M 3764 S 0 0.1 21.3 1:06 netscape 3135 root 1 0 1696 1696 1204 S 0 0.1 2.6 0:05 nxterm 3460 root 1 0 832 832 600 S 0 0.1 1.3 0:00 ssh 1 root 0 0 284 244 224 S 0 0.0 0.3 0:04 init 2 root 0 0 0 0 0 SW 0 0.0 0.0 0:00 kflushd 3 root -12 -12 0 0 0 SW< 0 0.0 0.0 0:00 kswapd 4 root 0 0 0 0 0 SW 0 0.0 0.0 0:00 md_thread 5 root 0 0 0 0 0 SW 0 0.0 0.0 0:00 md_thread 398 ivanov 0 0 520 468 412 S 0 0.0 0.7 0:00 startx 380 ivanov 0 0 740 644 524 S 0 0.0 1.0 0:00 zsh 362 root 0 0 228 196 180 S 0 0.0 0.3 0:00 gpm |
top показывает процессы по убыванию "потребления" процессора. ("top" -- верхушка, вверху показываются те процессы, которые потребляют больше). К сожалению, как видно из приведенного примера, сам top также потребляет немало -- на старых компьютерах типа 486 он иногда пожирал больше 10%.
<< Предыдущий раздел | /\ Содержание | >> Следующий раздел