Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Процессы_Практическая работа__.doc
Скачиваний:
2
Добавлен:
25.08.2019
Размер:
97.79 Кб
Скачать

Для информации (не выполнять)

Если необходимо изменить nice-фактор всех процессов одного пользователя, то используется ключ -u. Например, изменим nice-фактор всех процессов пользователя test:

test@adm-ubuntu:~$ ps lax | grep test 4 1001 13256 5630 20 0 8656 3036 wait S pts/1 0:00 su - test 0 1001 13297 13266 20 0 3056 824 pipe_w S+ pts/1 0:00 grep –color=auto test test@adm-ubuntu:~$ renice 5 -u test 1001: старый приоритет 0, новый приоритет 5 test@adm-ubuntu:~$ ps lax | grep test 4 1001 13256 5630 25 5 8656 3036 wait SN pts/1 0:00 su - test 0 1001 13302 13266 25 5 3056 820 pipe_w SN+ pts/1 0:00 grep –color=auto test

Для каких практических целей можно использовать nice-фактор? Например, если какие-то процессы занимают в данный момент большое количество процессорного времени, то для более быстрого определения проблемы можно запустить интерпретатор команд с более низким nice-фактором. Операции разного рода кодирования или сжатия, которые требуют много времени (часы), можно запускать с более высоким nice-фактором, чтобы не загружать систему. Быстродействие современных процессоров, таково, что к изменению nice-фактора прибегают все реже, но тем не менее иногда он может быть очень полезен.

Сигналы

В этом примере процесс less взаимодействует с процессом grep посредством механизма, который называется неименований канал или пайп (pipe - канал). Мы не будем вдаваться в подробности, просто запомните, что посредством символа |, который можно в данном случае называть “пайпом” информация (результат выполнения) процесса less идет на вход другого процесса - grep. Таким образом один процесс передал информацию другому процессу.

Еще один способ общения процессов - это именованные каналы. Изучение именованный каналов не входит в этот курс, но на практическом примере расскажу, что это. Именованный канал можно создать командой mkfifo: $ mkfifo my_pipe $ ls -l | grep my_pipe prw-r–r– 1 igor igor 0 2009-11-09 17:59 my_pipe

Теперь в одной консоли выполните команду:

$ echo Hello > my_pipe

Как видите команда не завершает свою работу, а ждет. Зарегистрируйтесь еще в одной консоли и выполните команду:

$ cat my_pipe Hello

Если вернуться на первую консоль, то вы увидите, что команда echo завершила свою работу. Таким образом через именованный канал my_pipe команда (процесс) echo передала информацию (слово Hello) процессу cat, который ее принял и вывел на экран.

Давайте теперь рассмотрим основной способ “общения” процессов - сигналы. Один процесс при помощи ядра может передать другому процессу специальное числовое значение сигнала. Процесс вызывает функцию передачи сигнала и передает необходимую информацию (код сигнала, PID процесса) ядру. Ядро передает сигнал процессу получателю и отслеживает как этот сигнал обрабатывается. Сигналы обозначаются цифрами или мнемоническими обозначениями. Перечень сигналов можно вывести командой kill -l.

Мнемонические имена которые вы видите (SIGTERM, SIGINT, SIGKILL) начинаются с приставки SIG. Имена в этом виде используются в языках программирования таких как С. В интерпретаторе bash используются или числа или мнемонические имена, но без приставки SIG - TERM, INT, KILL.

Часть сигналов (INT, TERM) являются перехватываемыми. Это означает, что процесс при получении такого сигнала должен перейти на специальную подпрограмму, которая занимается обработкой сигнала. Если подпрограммы обработки нет (а ее написанием занимаются разработчики программы, которая выполняется в контексте процесса), то управление передается ядру, которое выполняет действия по умолчанию, описанные для каждого сигнала.

Часть сигналов являются такими которые можно заблокировать. Например, один процесс посылает сигнал TERM другому процессу, а он в свою очередь не закончил операции ввода/вывода. В таком случае второй процесс может заблокировать полученный сигнал (опять таки в обработчике сигнала) до момента выполнения необходимой операции ввода/вывода. Сигнал TERM - это сигнал корректного завершения работы процесса. Обработчик этого сигнала, должен выполнить все необходимые действия для правильного завершения работы.

И есть третья группа сигналов, которые не блокируются и для которых не нужны обработчики. Примером такого сигнала является сигнал KILL. Этот сигнал уничтожает процесс, так как для него нет обработчиков в процессах, то он будет обрабатываться ядром по умолчанию и так как он не блокируемый, то действия будут выполнятся немедленно.

Пока мы говорили о том как процессы “общаются” между собой с помощью сигналов. Но мы (пользователи) также можем посылать сигналы процессам. Например, комбинация клавиш Ctrl+C посылает процессу сигнал INT, который прерывает выполнение процесса. Если вы наберете в терминале команду sleep 100, то команда не вернет управление терминалу пока не завершится. Прервать выполнение этой команды можно нажав комбинацию клавиш Ctrl+C.

В чем же отличия между похожими сигналами INT, TERM, KILL (а также QUIT и HUP)? Несмотря на похожесть отличия есть:

Сигнал KILL не блокируется и не перехватывается и ведет к немедленному завершению процесса. Сигнал INT в отличии от KILL является блокируемым сигналом и перехватываемым. Сигнал TERM также является перехватываемым и блокируемым и предназначен для корректного (предпочтительного) завершения работы процесса. Сигнал QUIT - похож на TERM, но позволяет сохранить дамп памяти. Сигнал HUP - сейчас этот сигнал чаще всего интерпретируется процессами как “прочесть конфигурационные файлы”.

Рассмотрим два сигнала: STOP и CONT. Сигнал STOP останавливает процесс, то есть процесс переходит в состояние “остановленный“. В таком состоянии процесс будет до тех пор пока снова не получит сигнал. Если будет получен сигнал CONT, то процесс возобновит свою работу с того момента как он был остановлен. Практический пример:

Наберите в терминале команду sleep 1000 &.

Затем проверьте, что процесс находится в состоянии ожидания, о чем нам говорит буква S в столбце STAT:

$ ps x | grep [s]leep PID TTY STAT TIME COMMAND 6301 pts/1 S 0:00 sleep 1000

Теперь пошлем процессу сигнал STOP. Для этого используем команду kill (kill -название процесса PID процесса):

$ kill -STOP 6301 [1]+ Stopped sleep 1000

Проверяем статус процесса: $ ps x | grep [s]leep PID TTY STAT TIME COMMAND 6301 pts/1 T 0:00 sleep 1000

Видим, что процесс действительно находится в состоянии “остановленный” (символ T в столбце STAT).

Теперь отправим процессу сигнал продолжения работы (CONT) и проверим состояние: kill -CONT 6301 $ ps x | grep [s]leep PID TTY STAT TIME COMMAND 6301 pts/1 S 0:00 sleep 1000

Если необходимо корректно завершить процесс, то необходимо послать ему сигнал TERM: $ kill -TERM 6301 $ ps x | grep [s]leep [1]+ Terminated sleep 1000 $ ps x | grep [s]leep

Если сразу же после посылки сигнала TERM выполнить команду ps x | grep [s]leep, то можно успеть увидеть сообщение о том, что процесс завершает работу, в при следующей попытке вывести информацию о нашем процессе sleep мы уже ничего не увидим - процесс прекратил существование. Команда kill без указания сигнала, по умолчанию передает процессу именно сигнал TERM. Поэтому можно было написать просто kill 6301.

Если необходимо срочно завершить процесс, или процесс не завершается по сигналу TERM, то тогда необходимо послать процессу сигнал KILL: $ sleep 1000 & [1] 6348 $ kill -KILL 6348 $ ps x | grep [s]leep [1]+ Killed sleep 1000

Если необходимо послать один и тот же сигнал нескольким процессам, то можно перечислить их через пробел: kill -TERM 2345 3456 4567.

Команда kill довольно ограничена в возможностях и не позволяет выполнять более сложные действия. Поэтому рассмотрим еще одну команду - killall. Основное преимущество этой команды, то что она умеет посылать сигналы всем процессам с одинаковым именем или всем процессам одного пользователя. Запустите несколько раз подряд команду sleep 1000 &:

$ ps x | grep [s]leep 6460 pts/1 S 0:00 sleep 1000 6461 pts/1 S 0:00 sleep 1000 6462 pts/1 S 0:00 sleep 1000 6463 pts/1 S 0:00 sleep 1000 6464 pts/1 S 0:00 sleep 1000 6465 pts/1 S 0:00 sleep 1000 6466 pts/1 S 0:00 sleep 1000

Теперь, чтобы завершить все процессы с именем sleep, достаточно набрать команду killall sleep: $ killall sleep [1] Terminated sleep 1000 [2] Terminated sleep 1000 [3] Terminated sleep 1000 [4] Terminated sleep 1000 [6]- Terminated sleep 1000 [7]+ Terminated sleep 1000 [5]+ Terminated sleep 1000

Выполните команду sleep 1000 & еще несколько раз, а затем зарегистрируйтесь в другой консоли от имени другого пользователя (например, test) и также от его имени выполните команду sleep 1000 &. Теперь вернитесь в свою консоль и просмотрите процессы sleep всех пользователей:

$ ps aux | grep [s]leep igor 6540 0.0 0.0 2952 628 pts/1 S 22:30 0:00 sleep 1000 igor 6541 0.0 0.0 2952 632 pts/1 S 22:30 0:00 sleep 1000 igor 6542 0.0 0.0 2952 628 pts/1 S 22:30 0:00 sleep 1000 test 6543 0.0 0.0 2952 632 pts/3 S 22:30 0:00 sleep 1000 test 6544 0.0 0.0 2952 628 pts/3 S 22:30 0:00 sleep 1000 test 6545 0.0 0.0 2952 628 pts/3 S 22:30 0:00 sleep 1000 test 6546 0.0 0.0 2952 632 pts/3 S 22:30 0:00 sleep 1000

Теперь для того, чтобы удалить процессы только пользователя test необходимо выполнить (от имени пользователя root) команду killall -u test: igor@ubuntu:~$ sudo killall -u test igor@ubuntu:~$ ps aux | grep [s]leep igor 6540 0.0 0.0 2952 628 pts/1 S 22:30 0:00 sleep 1000 igor 6541 0.0 0.0 2952 632 pts/1 S 22:30 0:00 sleep 1000 igor 6542 0.0 0.0 2952 628 pts/1 S 22:30 0:00 sleep 1000

Команда выше удалит не только процессы sleep, но вообще все процессы пользователя test. Если необходимо удалить конкретно процессы sleep, то тогда команду нужно было записать так: killall -u test sleep.

Если запустить команду killall c ключом -i, то перед посылкой сигнала будет запрашиваться подтверждение:

igor@ubuntu:~$ killall -i sleep Прибить sleep(6540) ? (y/N) n Прибить sleep(6541) ? (y/N) n Прибить sleep(6542) ? (y/N) n

ЗАДАНИЯ (JOBS), КОМАНДЫ JOBS, FG, BG, STRONG>NOHUP, И TOP.

закончим тему процессов и сигналов в Linux и перейдем к теме монтирования файловых систем. На прошлой лекции мы неоднократно использовали знак & (амперсанд) в конце команды (sleep 100 &). Знак амперсанда в конце команды означает, что запускаемый процесс нужно будет перевести в фоновый режим.Если запустить команду sleep 100 без знака &, то мы не получим приглашение в командной строке пока не будет завершен процесс sleep.

Запущенные из консоли с помощью амперсанда команды, работают в фоновом режиме и называются задачами (jobs). Можно сказать, что задачи это процессы, привязанные к командному интерпретатору. Такие задачи помимо традиционного PID имеют еще свою нумерацию начинающуюся с единицы. Просмотреть запущенные задачи интерпретатора, можно командой jobs. В примере ниже показана ситуация когда есть две задачи и выполнение одного из них остановлено.

1 2 3

$ jobs [1]+  Stopped                 top [2]-  Running                 sleep 100 &

Наберите в консоли команду top. Эта команда показывает в реальном времени существующие процессы, но не все, а только ту часть которая помещается на экране. Чуть позже мы вернемся к этой команде. Пока вы можете заметить, что top не возвращает управление командному интерпретатору. Можно либо выйти из программы (нажав q) или остановить процесс комбинацией клавиш ctrl+z (не путайте комбинации ctrl+c - завершение процесса и ctrl+z - остановка процесса). Остановленный процесс top мы и видели на примере выше. Для того, чтобы возобновить работу данного процесса (задачи) есть две команды: fg и bg, сокращения от английских слов foreground (передний план) и background (задний план). Синтаксис простой: fg номер задачи. Команда fg, работает не только с остановленными задачами, но и с задачами вообще. В нашем примере команда fg 2 выведет процесс sleep на передний план и приглашение командного интерпретатора станет недоступным (так как будто мы запустили команду sleep без символа &). Команда fg 2 возобновит работу процесса top и выведет его на передний план. Команда fg без параметра возобновит работу последнего процесса остановленного комбинацией ctrl+z, а если таковых не окажется, то выведет на передний план последнюю задачу (задачу с большим порядковым номером). Задача, которая будет восстановлена (отображена) командой fg без параметра отмечена знаком + в выводе результатов команды jobs. Команда bg предназначена для восстановления работы остановленных процессов (задач) в фоновом режиме.

Отметьте для себя также, что задачи имеют свою нумерацию для каждого терминала (консоли). Если вы зарегистрируетесь в другой консоли и запустите в фоновом режиме процесс, то номер задачи будет начинаться с единицы. Также вы не найдете справки по командам fg и bg (man fg, man bg). Потому, что эти команды являются частью bash. И упоминание о них вы найдете в man bash.

Любые процессы запущенные из командного интерпретатора являются дочерними для него. И PPID таких процессов будет равен PID соответствующего командного интерпретатора. Если выйти из командного интерпретатора, то все процессы запущенные из него (в том числе и находящиеся в фоновом режиме) будут завершены. Зарегистрируйтесь в двух консолях и запустите во второй несколько процессов, перейдите в первую и выполните команду ps al:

1 2 3 4 5 6 7 8 9

$ ps al F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND 0  1000 13180  1053  20   0   6292  3552 wait   Ss   pts/0      0:00 bash 0  1000 16442  1054  20   0   6292  3560 wait   Ss   pts/1      0:00 bash 0  1000 16460 16442  20   0   2952   628 signal T    pts/1      0:00 sleep 200 0  1000 16461 16442  20   0  18416  4392 signal T    pts/1      0:00 mocp 0  1000 16469 16442  20   0   2952   628 hrtime S    pts/1      0:00 sleep 1000 0  1000 16470 16442  20   0   2468  1208 poll_s S+   pts/1      0:00 top 0  1000 16473 13180  20   0   2424   828 -      R+   pts/0      0:00 ps al

В примере у нас запущено два командных интерпретатора bash с PID равными 13180 и 16442. Далее идут 4-е процесса, которые были запущены из второго командного интерпретатора - их можно определить по PPID равному 16442. Теперь выйдите (команда exit) из второго интерпретатора и снова выполните команду ps al в первом интерпретаторе:

1 2 3 4

$ ps al F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND 0  1000 13180  1053  20   0   6292  3556 wait   Ss   pts/0      0:00 bash 0  1000 16679 13180  20   0   2424   824 -      R+   pts/0      0:00 ps al

Как видим завершился не только процесс с PID 16442, но и все процессы потомки (PPID 16442). Еще одно подтверждение того, что процесс-потомок не может существовать без родительского процесса.

Но, что делать если необходимо запустить процесс, и выйти из консоли так чтобы процесс продолжал работать в системе? Выход один - передать процесс-потомок другому процессу, который будет для него родительским. Такая возможность реализована в команде nohup. Данная команда позволяет запускать процессы, который будут оторваны от терминала если, терминал будет закрыт. Проводим эксперимент. Запускаем любую команду (например ping) через nohup в одной консоли и не выходя из нее смотрим на процессы:

1

$ nohup ping 127.0.0.1 &

1 2 3 4 5 6

$ ps alx F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND 4       0 17326       1  20   0   7908  3208 wait   Ss   tty2       0:00 /bin/login --     4  1000 17427 17326  20   0   6304  3560 wait   S    tty2       0:00 -bash 4  1000 17450 17427  20   0   1848   556 wait_f S    tty2       0:00 ping 127.0.0.1 0  1000 17517 13180  20   0   2424   848 -      R+   pts/0      0:00 ps alx

Видим, что сейчас процесс ping имеют PPID равный 17427 (то есть это потомок командного интерпретатора bash) и PID 17450. Теперь выйдем из командного интерпретатора bash с PID 17427 и снова посмотрим на процессы:

1 2 3

$ ps alx F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND 4  1000 17450     1  20   0   1848   556  poll_s        S    ?          0:00 ping 127.0.0.1

Как видим несмотря на то, что мы вышли из командного интерпретатора, процесс с PID 17450 остался в системе и принял в качестве родительского, процесс с PID равным 1, то есть процесс init. Процесс 17450 будет существовать до тех пор пока будет существовать процесс init, или пока мы сами не завершим его работу с помощью команды kill.

Команда ps показывает очень подробную информацию о процессах, но она почти бесполезна если нужно отследить работу процесса в реальном времени, просмотреть какие ресурсы и в каком количестве занимает процесс. Для этого существует другая команда - top. Команда top работает в интерактивном режиме и в режиме реального времени отображает работу процессов. Чтобы запустить нужно просто набрать команду - top. Выход - клавиша q. Процессы отображены не все, а только верхняя часть таблицы процессов отсортированная по какому-либо критерию (столбцу).