Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Администрирование систем Linux. Вводная информация об управлении процессами

Оригинал: Introduction to processes
Автор: Paul Cobbaut
Дата публикации: 12 марта 2015 г.
Перевод: А. Панин
Дата перевода: 28 марта 2015 г.

Часть I. Управление процессами

Глава 1. Вводная информация об управлении процессами

1.1. Терминология

1.1.1. Процесс

Процесс является скомпилированным исходным кодом, исполняющимся в текущее время в системе.

1.1.2. Идентификатор процесса PID

Каждый из процессов имеет идентификатор или PID (сокращение process id).

1.1.3. Идентификатор родительского процесса PPID

Каждый процесс имеет родительский процесс (который идентифицируется с помощью идентификатора родительского процесса или PPID). Дочерний процесс обычно запускается средствами родительского процесса.

1.1.4. Процесс init

Процесс init всегда имеет идентификатор PID, равный 1. Процесс init запускается средствами ядра операционной системы и, следовательно, не имеет родительского процесса. Процесс init исполняет обязанности приемного родителя для осиротевших процессов.

1.1.5. Уничтожение процесса

Завершение работы процесса чаще всего достигается благодаря его уничтожению, поэтому в том случае, если вы хотите остановить исполнение процесса, вы должны уничтожить его.

1.1.6. Демон

Процессы, которые запускаются в момент загрузки системы и исполняются в течение всего времени функционирования системы, называются процессами-демонами или просто демонами. Демоны никогда не должны самостоятельно завершать свою работу.

1.1.7. Зомби

Уничтоженный процесс, информация о котором сохраняется в рамках системы, называется зомби-процессом. Вы не можете уничтожить зомби-процессы, так как они уже были уничтожены ранее и не исполняются.

1.2. Базовые приемы управления процессами

1.2.1. Переменные командной оболочки $$ и $PPID

Некоторые переменные командной оболочки содержат информацию о процессах. Переменная $$ будет хранить идентификатор используемого вами в данный момент процесса командной оболочки, а переменная $PPID - идентификатор соответствующего родительского процесса. На самом деле $$ является параметром командной оболочки, а не переменной, так как вы не можете установить значение этого параметра.

Ниже приведен пример использования утилиты echo для вывода значений $$ и $PPID.

[paul@RHEL4b ~]$ echo $$ $PPID
4224 4223

1.2.2. Утилита pidof

Вы можете получить все идентификаторы процессов на основе известного имени процесса, воспользовавшись утилитой pidof.

root@rhel53 ~# pidof mingetty
2819 2798 2797 2796 2795 2794

1.2.3. Родительские и дочерние процессы

Иерархия процессов системы строится на отношении родительский процесс - дочерний процесс. Каждый процесс в системе имеет родительский процесс.

При запуске нового экземпляра командной оболочки bash вы можете воспользоваться утилитой echo, чтобы убедиться в том, что идентификатор процесса предыдущего экземпляра командной оболочки совпадает с идентификатором родительского процесса нового экземпляра командной оболочки. Таким образом, используемый ранее дочерний процесс в данном случае становится родительским процессом.

[paul@RHEL4b ~]$ bash
[paul@RHEL4b ~]$ echo $$ $PPID
4812 4224

Ввод команды exit приведет к завершению исполнения текущего процесса и возврату в командную оболочку с оригинальными значениями $$ и $PPID.

[paul@RHEL4b ~]$ echo $$ $PPID
4812 4224
[paul@RHEL4b ~]$ exit
exit
[paul@RHEL4b ~]$ echo $$ $PPID
4224 4223
[paul@RHEL4b ~]$

1.2.4. Системные вызовы fork и exec

Процесс инициирует исполнение другого процесса в два этапа. На первом этапе он создает свою точную копию с помощью системного вызова fork. После этого в рамках копии процесса выполняется системный вызов exec, предназначенный для замены скопированных данных родительского процесса на данные дочернего процесса.

[paul@RHEL4b ~]$ echo $$
4224
[paul@RHEL4b ~]$ bash
[paul@RHEL4b ~]$ echo $$ $PPID
5310 4224
[paul@RHEL4b ~]$

1.2.5. Команда exec

Благодаря команде exec вы можете инициировать исполнение нового процесса, минуя этап создания точной копии текущего процесса. В следующем примере осуществляется запуск командной оболочки Korn Shell (ksh) с последующей заменой на командную оболочку bash с помощью команды exec. Идентификатор процесса командной оболочки bash остается равным идентификатору процесса командной оболочки Korn Shell. При этом после завершения работы с дочерней командной оболочкой bash происходит перемещение в родительскую командную оболочку bash, а не в командную оболочку Korn shell (процесса которой более не существует).

[paul@RHEL4b ~]$ echo $$
4224 # PID процесса bash
[paul@RHEL4b ~]$ ksh
$ echo $$ $PPID
5343 4224 # PID процессов ksh и bash
$ exec bash
[paul@RHEL4b ~]$ echo $$ $PPID
5343 4224 # PID процессов bash и bash
[paul@RHEL4b ~]$ exit
exit
[paul@RHEL4b ~]$ echo $$
4224

1.2.6. Утилита ps

Одним из наиболее часто используемых инструментов для ознакомления со списком процессов в Linux является утилита ps. В следующем примере показаны отношения между тремя родительскими и дочерними процессами bash.

[paul@RHEL4b ~]$ echo $$ $PPID
4224 4223
[paul@RHEL4b ~]$ bash
[paul@RHEL4b ~]$ echo $$ $PPID
4866 4224
[paul@RHEL4b ~]$ bash
[paul@RHEL4b ~]$ echo $$ $PPID
4884 4866
[paul@RHEL4b ~]$ ps fx
 PID TTY      STAT   TIME COMMAND
4223 ?        S      0:01 sshd: paul@pts/0 
4224 pts/0    Ss     0:00  \_ -bash
4866 pts/0    S      0:00      \_ bash
4884 pts/0    S      0:00          \_ bash
4902 pts/0    R+     0:00              \_ ps fx
[paul@RHEL4b ~]$ exit
exit
[paul@RHEL4b ~]$ ps fx
 PID TTY      STAT   TIME COMMAND
4223 ?        S      0:01 sshd: paul@pts/0 
4224 pts/0    Ss     0:00  \_ -bash
4866 pts/0    S      0:00      \_ bash
4903 pts/0    R+     0:00          \_ ps fx
[paul@RHEL4b ~]$ exit
exit
[paul@RHEL4b ~]$ ps fx
 PID TTY      STAT   TIME COMMAND
4223 ?        S      0:01 sshd: paul@pts/0 
4224 pts/0    Ss     0:00  \_ -bash
4904 pts/0    R+     0:00      \_ ps fx
[paul@RHEL4b ~]$ 

В Linux обычно используется команда ps fax. В Solaris же чаще всего используется команда ps -ef (которая также работает в Linux). Ниже приведен фрагмент вывода команды ps fax.

[paul@RHEL4a ~]$ ps fax
 PID TTY      STAT   TIME COMMAND
   1 ?        S      0:00 init [5]

...

3713 ?        Ss     0:00 /usr/sbin/sshd
5042 ?        Ss     0:00  \_ sshd: paul [priv]
5044 ?        S      0:00      \_ sshd: paul@pts/1 
5045 pts/1    Ss     0:00           \_ -bash
5077 pts/1    R+     0:00               \_ ps fax

1.2.7. Утилита pgrep

По аналогии с командой ps -C, вы также можете использовать утилиту pgrep для поиска информации о процессе по его имени.

[paul@RHEL5 ~]$ sleep 1000 &
[1] 32558
[paul@RHEL5 ~]$ pgrep sleep
32558
[paul@RHEL5 ~]$ ps -C sleep
  PID TTY          TIME CMD
32558 pts/3    00:00:00 sleep

Кроме того, вы можете осуществлять вывод списка найденных идентификаторов процессов с соответствующими им именами процессов.

paul@laika:~$ pgrep -l sleep
9661 sleep

1.2.8. Утилита top

Другим популярным инструментом для получения информации о процессах в Linux является утилита top. Утилита top может упорядочивать список процессов в соответствии с создаваемой ими нагрузкой на центральный процессор, а также с другими параметрами. Кроме того, вы можете уничтожать процессы средствами утилиты top. Нажмите клавишу h в процессе работы с утилитой top для ознакомления со справочной информацией.

В случае неполадок утилита top является первым инструментом, который следует применять для диагностики системы, так как помимо информации о процессах она может предоставить информацию об использовании оперативной памяти и раздела подкачки вашей системы.

1.3. Отправка сигналов процессам

1.3.1. Утилита kill

Утилита kill позволяет уничтожить процесс (или остановить его исполнение). В примере ниже показана стандартная методика использования утилиты kill для остановки исполнения процесса с идентификатором 1942.

paul@ubuntu910:~$ kill 1942
paul@ubuntu910:~$

На самом деле в процессе использования утилиты kill осуществляется передача сигнала процессу.

1.3.2. Список сигналов

Исполняющиеся процессы могут принимать сигналы от других процессов, а также от пользователей. Вы можете получить список сигналов, воспользовавшись командой kill -l, причем в качестве параметра должна использоваться строчная буква l, а не число 1.

[paul@RHEL4a ~]$ kill -l
1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL
5) SIGTRAP      6) SIGABRT      7) SIGBUS       8) SIGFPE
9) SIGKILL     10) SIGUSR1     11) SIGSEGV     12) SIGUSR2
13) SIGPIPE     14) SIGALRM     15) SIGTERM     17) SIGCHLD
18) SIGCONT     19) SIGSTOP     20) SIGTSTP     21) SIGTTIN
22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO
30) SIGPWR      31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1
36) SIGRTMIN+2  37) SIGRTMIN+3  38) SIGRTMIN+4  39) SIGRTMIN+5
40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8  43) SIGRTMIN+9
44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13
52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9
56) SIGRTMAX-8  57) SIGRTMAX-7  58) SIGRTMAX-6  59) SIGRTMAX-5
60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2  63) SIGRTMAX-1
64) SIGRTMAX
[paul@RHEL4a ~]$ 

1.3.3. Команда kill -1 (SIGHUP)

Первый сигнал SIGHUP (или HUP, или 1) часто используется в Linux для сообщения процессу о необходимости повторного чтения файла конфигурации. Таким образом, команда kill -1 1 приведет к принудительному повторному чтению файла конфигурации процессом init (процесс init всегда имеет идентификатор 1).

root@deb503:~# kill -1 1
root@deb503:~#

Решение о том, должен ли процесс осуществлять повторное чтение файла конфигурации в процессе работы или после перезапуска, принимается исключительно разработчиком соответствующего приложения. Перед отправкой данного сигнала пользователю следует ознакомиться с документацией, поставляемой совместно с приложением.

1.3.4. Команда kill -15 (SIGTERM)

Сигнал SIGTERM также часто называется стандартным сигналом уничтожения процесса. При использовании утилиты kill без указания сигнала предполагается, что исполняется команда kill -s 15.

Команды в примере ниже являются идентичными.

paul@ubuntu910:~$ kill 1942
paul@ubuntu910:~$ kill -15 1942

1.3.5. Команда kill -9 (SIGKILL)

Сигнал SIGKILL отличается от большинства сигналов тем, что он отправляется не процессу, а непосредственно ядру Linux. Команда kill -9 также называется надежной командной уничтожения процесса. Ядро операционной системы гарантированно завершит исполнение указанного процесса. Как разработчик вы не можете ни коим образом перехватить сигнал, генерируемый в результате исполнения команды kill -9.

root@rhel53 ~# kill -9 3342

1.3.6. Сигналы SIGSTOP и SIGCONT

Исполнение процесса может быть приостановлено в случае приема сигнала SIGSTOP. Данный сигнал может быть отправлен процессу с помощью команды kill -19 в Linux, причем в других системах Unix номер сигнала может отличаться.

Приостановленный процесс не использует циклов центрального процессора, но находится в памяти и может быть реанимирован с помощью сигнала SIGCONT (отправляемого с помощью команды kill -18 в Linux).

Оба этих сигнала будут использоваться в главе, посвященной описанию процессов, исполняющихся в фоновом режиме.

1.3.7. Утилита pkill

Вы можете использовать утилиту pkill для завершения работы процесса на основе его имени.

[paul@RHEL5 ~]$ sleep 1000 &
[1] 30203
[paul@RHEL5 ~]$ pkill sleep
[1]+  Завершено      sleep 1000
[paul@RHEL5 ~]$ 

1.3.8. Утилита killall

Утилита killall позволяет отправлять сигнал 15 всем процессам с определенным именем.

paul@rhel65:~$ sleep 8472 &
[1] 18780
paul@rhel65:~$ sleep 1201 &
[2] 18781
paul@rhel65:~$ jobs
[1]- Running         sleep 8472 &
[2]+ Running         sleep 1201 &
paul@rhel65:~$ killall sleep
[1]-  Завершено      sleep 8472
[2]+  Завершено      sleep 1201
paul@rhel65:~$ jobs
paul@rhel65:~$

1.3.9. Утилита killall5

Аналог описанной выше утилиты из мира SysV, утилита killall5, может использоваться в процессе завершения работы системы. В данном примере показано, как утилита killall5 используется в дистрибутиве Red Hat Enterprise Linux 5.3 для уничтожения процессов при завершении работы системы.

root@rhel53 ~# grep killall /etc/init.d/halt
action $"Sending all processes the TERM signal..." /sbin/killall5 -15
action $"Sending all processes the KILL signal..." /sbin/killall5 -9

1.3.10. Утилита top

При работе с утилитой top кнопка k позволит вам выбрать сигнал и идентификатор процесса, которому этот сигнал будет отправлен. В примере ниже приведена строка, выводимая под строками с общей информацией о состоянии системы после нажатия клавиши k.

PID to signal/kill [default pid = 977] 1932

Send pid 1932 signal [15/sigterm] 9

1.4. Практическое задание: вводная информация об управлении процессами

1. Используйте утилиту ps для поиска информации о процессе с именем init.

2. Каков идентификатор процесса с именем init?

3. Используйте команду who i am для установления имени пользователя, под которым вы работаете с терминалом.

4. Располагая полученной ранее информацией о вашем имени пользователя, примените утилиту ps для поиска всех процессов, запущенных с помощью вашего терминала.

5. Каков идентификатор процесса вашей командной оболочки?

6. Каков идентификатор родительского процесса вашей командной оболочки?

7. Запустите в фоновом режиме два экземпляра процесса с помощью команд sleep 3342.

8. Определите идентификаторы всех процессов с именем sleep.

9. Выведите информацию только о двух запущенных ранее процессах sleep с помощью утилиты top. После этого завершите работу утилиты top.

10. Используйте стандартный сигнал уничтожения процесса для уничтожения одного из двух созданных ранее процессов с именами sleep.

11. Используйте одну команду для уничтожения всех процессов с именем sleep.

1.5. Корректная процедура выполнения практического задания: вводная информация об управлении процессами

1. Используйте утилиту ps для поиска информации о процессе с именем init.

root@rhel53 ~# ps -C init
  PID TTY          TIME CMD
    1 ?        00:00:04 init

2. Каков идентификатор процесса с именем init?

1

3. Используйте команду who i am для установления имени пользователя, под которым вы работаете с терминалом.

root@rhel53 ~# who am i
paul     pts/0        2010-04-12 17:44 (192.168.1.38)

4. Располагая полученной ранее информацией о вашем имени пользователя, примените утилиту ps для поиска всех процессов, запущенных с помощью вашего терминала.

root@rhel53 ~# ps fax | grep pts/0
2941 ?        S      0:00      \_ sshd: paul@pts/0 
2942 pts/0    Ss     0:00          \_ -bash
2972 pts/0    S      0:00              \_ su -
2973 pts/0    S      0:00                  \_ -bash
3808 pts/0    R+     0:00                      \_ ps fax
3809 pts/0    R+     0:00                      \_ grep pts/0

или может быть использована аналогичная команда

root@rhel53 ~# ps -ef | grep pts/0
paul      2941  2939  0 17:44 ?        00:00:00 sshd: paul@pts/0 
paul      2942  2941  0 17:44 pts/0    00:00:00 -bash
root      2972  2942  0 17:45 pts/0    00:00:00 su -
root      2973  2972  0 17:45 pts/0    00:00:00 -bash
root      3816  2973  0 21:25 pts/0    00:00:00 ps -ef
root      3817  2973  0 21:25 pts/0    00:00:00 grep pts/0

5. Каков идентификатор процесса вашей командной оболочки?

2973 в примере выше, в вашем случае наверняка будет использоваться отличный идентификатор процесса

Команда echo $$ позволит получить аналогичное найденному значение

6. Каков идентификатор родительского процесса вашей командной оболочки?

2972 в примере выше, в вашем случае наверняка будет использоваться отличный идентификатор родительского процесса

В данном примере родительским процессом является процесс su -, в то время, как при работе в окружении рабочего стола gnome родительским процессом может оказаться процесс gnome-terminal

7. Запустите в фоновом режиме с помощью команд sleep 3342 два экземпляра процесса.

sleep 3342 &
sleep 3342 &

8. Определите идентификаторы всех процессов с именем sleep.

pidof sleep

9. Выведите информацию только о двух запущенных ранее процессах sleep с помощью утилиты top. После этого завершите работу утилиты top.

top -p pidx,pidy (замените pidx, pidy на действительные значения идентификаторов процессов)

10. Используйте стандартный сигнал уничтожения процесса для уничтожения одного из двух созданных ранее процессов с именами sleep.

kill pidx

11. Используйте одну команду для уничтожения всех процессов с именем sleep.

pkill sleep

Предыдущий раздел: Оглавление Следующий раздел:
Аннотация   Глава 2. Приоритеты процессов