Версия для печати

Архив документации на OpenNet.ru / Раздел "Программирование в Linux" (Многостраничная версия)

Процессы в Linux


Оригинал: dkws.narod.ru
Автор: Колисниченко Денис, dhsilabs@mail.ru

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

Немного теории

Термин "процесс" впервые появился при разработке операционной системы Multix и имеет несколько определений, которые используются в зависимости от контекста. Процесс - это:

  1. программа на стадии выполнения
  2. "объект", которому выделено процессорное время
  3. асинхронная работа

Для описания состояний процессов используется несколько моделей. Самая простая модель - это модель трех состояний. Модель состоит из:

  1. состояния выполнения
  2. состояния ожидания
  3. состояния готовности

Выполнение - это активное состояние, во время которого процесс обладает всеми необходимыми ему ресурсами. В этом состоянии процесс непосредственно выполняется процессором.

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

Готовность - это тоже пассивное состояние, процесс тоже заблокирован, но в отличие от состояния ожидания, он заблокирован не по внутренним причинам (ведь ожидание ввода данных - это внутренняя, "личная" проблема процесса - он может ведь и не ожидать ввода данных и свободно выполняться - никто ему не мешает), а по внешним, независящим от процесса, причинам. Когда процесс может перейти в состояние готовности? Предположим, что наш процесс выполнялся до ввода данных. До этого момента он был в состоянии выполнения, потом перешел в состояние ожидания - ему нужно подождать, пока мы введем нужную для работы процесса информацию. Затем процесс хотел уже перейти в состояние выполнения, так как все необходимые ему данные уже введены, но не тут-то было: так как он не единственный процесс в системе, пока он был в состоянии ожидания, его "место под солнцем" занято - процессор выполняет другой процесс. Тогда нашему процессу ничего не остается как перейти в состояние готовности: ждать ему нечего, а выполняться он тоже не может.

Из состояния готовности процесс может перейти только в состояние выполнения. В состоянии выполнения может находится только один процесс на один процессор. Если у вас n-процессорная машина, у вас одновременно в состоянии выполнения могут быть n процессов.

Из состояния выполнения процесс может перейти либо в состояние ожидания или состояние готовности. Почему процесс может оказаться в состоянии ожидания, мы уже знаем - ему просто нужны дополнительные данные или он ожидает освобождения какого-нибудь ресурса, например, устройства или файла. В состояние готовности процесс может перейти, если во время его выполнения, квант времени выполнения "вышел". Другими словами, в операционной системе есть специальная программа - планировщик, которая следит за тем, чтобы все процессы выполнялись отведенное им время. Например, у нас есть три процесса. Один из них находится в состоянии выполнения. Два других - в состоянии готовности. Планировщик следит за временем выполнения первого процесса, если "время вышло", планировщик переводит процесс 1 в состояние готовности, а процесс 2 - в состояние выполнения. Затем, когда, время отведенное, на выполнение процесса 2, закончится, процесс 2 перейдет в состояние готовности, а процесс 3 - в состояние выполнения.

Диаграмма модели трех состояний представлена на рисунке 1.


Рисунок 1. Модель трех состояний

Более сложная модель - это модель, состоящая из пяти состояний. В этой модели появилось два дополнительных состояния: рождение процесса и смерть процесса. Рождение процесса - это пассивное состояние, когда самого процесса еще нет, но уже готова структура для появления процесса. Как говорится в афоризме: "Мало найти хорошее место, надо его еще застолбить", так вот во время рождения как раз и происходит "застолбление" этого места. Смерть процесса - самого процесса уже нет, но может случиться, что его "место", то есть структура, осталась в списке процессов. Такие процессы называются зобми и о них мы еще поговорим в этой статье.

Диаграмма модели пяти состояний представлена на рисунке 2.


Рисунок 2. Модель пяти состояний

Над процессами можно производить следующие операции:

  1. Создание процесса - это переход из состояния рождения в состояние готовности
  2. Уничтожение процесса - это переход из состояния выполнения в состояние смерти
  3. Восстановление процесса - переход из состояния готовности в состояние выполнения
  4. Изменение приоритета процесса - переход из выполнения в готовность
  5. Блокирование процесса - переход в состояние ожидания из состояния выполнения
  6. Пробуждение процесса - переход из состояния ожидания в состояние готовности
  7. Запуск процесса (или его выбор) - переход из состояния готовности в состояние выполнения

Для создания процесса операционной системе нужно:

  1. Присвоить процессу имя
  2. Добавить информацию о процессе в список процессов
  3. Определить приоритет процесса
  4. Сформировать блок управления процессом
  5. Предоставить процессу нужные ему ресурсы

Подробнее о списке процессов, приоритете и обо всем остальном мы еще поговорим, а сейчас нужно сказать пару слов об иерархии процессов. Процесс не может взяться из ниоткуда: его обязательно должен запустить какой-то процесс. Процесс, запущенный другим процессом, называется дочерним (child) процессом или потомком. Процесс, который запустил процесс называется родительским (parent), родителем или просто - предком. У каждого процесса есть два атрибута - PID (Process ID) - идентификатор процесса и PPID (Parent Process ID) - идентификатор родительского процесса.

Процессы создают иерархию в виде дерева. Самым "главным" предком, то есть процессом, стоящим на вершине этого дерева, является процесс init (PID=1).

На мой взгляд, приведенной теории вполне достаточно, чтобы перейти к практике, а именно - "пощупать" все состояния процессов. Конечно, мы не рассмотрели системные вызовы fork(), exec(), exit(), kill() и многие другие, но в Сети предостаточно информации об этом. Тем более, что про эти вызовы вы можете прочитать в справочной системе Linux, введя команду man fork. Правда, там написано на всеми любимом English, так что за переводом (если он вам нужен) все-таки придется обратиться за помощью к WWW.

Практика

Для наблюдения за процессами мы будем использовать программу top.

15:03:11  up 58 min,  4 users,  load average: 0,02, 0,01, 0,00
52 processes: 51 sleeping, 1 running, 0 zombie, 0 stopped
CPU states:  0,8% user,  0,6% system,  0,0% nice,  0,0% iowait, 98,3% idle
Mem:   127560k av,  124696k used,    2864k free,       0k shrd,     660k buff
        13460k active,              17580k inactive
Swap:  152576k av,    8952k used,  143624k free                   28892k cached

 PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME COMMAND
 3097 den       15   0  1128 1128   832 R     2,8  0,8   0:00 top
    1 root       8   0   120   84    60 S     0,0  0,0   0:04 init
    2 root      12   0     0    0     0 SW    0,0  0,0   0:00 keventd
    3 root      19  19     0    0     0 SWN   0,0  0,0   0:00 ksoftirqd_CPU0
...

Полный вывод программы я по понятным причинам урезал. Рассмотрим по порядку весь вывод программы. В первой строке программа сообщает текущее время, время работы системы ( 58 min), количество зарегистрированных (login) пользователей (4 users), общая средняя загрузка системы (load average).

Примечание. Общей средней загрузкой системы называется среднее число процессов, находящихся в состоянии выполнения (R) или в состоянии ожидания (D). Общая средняя загрузка измеряется каждые 1, 5 и 15 минут.

Во второй строке вывода программы top сообщается, что в списке процессов находятся 52 процесса, из них 51 спит (состояние готовности или ожидания), 1 выполняется (у меня только 1 процессор), 0 процессов зомби и 0 остановленных процессов.

В третьей-пятой строках приводится информация о загрузке процессора, использования памяти и файла подкачки. Нас данная информация не очень интересует, поэтому переходим сразу к таблице процессов.

В таблице отображается различная информация о процессе. Нас сейчас интересуют колонки PID (идентификатор процесса), USER (пользователь, запустивший процесс), STAT (состояние процесса) и COMMAND (команда, которая была введена для запуска процесса).

Колонка STAT может содержать следующие значения:

Давайте просмотрим, когда же процесс находится в каждом состоянии. Создайте файл process - это обыкновенный bash-сценарий

#!/bin/bash
x=1
while [ $x -lt 10 ]
do
x=2
done

Сделайте этот файл исполнимым chmod +x ./process и запустите его ./process. Теперь перейдите на другую консоль (ALT + Fn) и введите команду ps -a | grep process. Вы увидите следующий вывод команды ps:

 4035 pts/1    00:00:15 process

Данный вывод означает, что нашему процессу присвоен идентификатор процесса 4035. Теперь введите команду top -p 4035

15:30:15  up  1:25,  6 users,  load average: 0,44, 0,19, 0,07
1 processes: 0 sleeping, 1 running, 0 zombie, 0 stopped
CPU states:  2,3% user,  0,6% system,  0,0% nice,  0,0% iowait, 96,8% idle
Mem:   127560k av,  124496k used,    3064k free,       0k shrd,    1208k buff
        15200k active,              16400k inactive
Swap:  152576k av,   15676k used,  136900k free                   27548k cached

  PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME COMMAND
 4035 den       15   0  1320 1320   988 R    99,9  1,0   0:31 process

Обратите внимание на колонку состояния нашего процесса. Она содержит значение R, которое означает, что в данный момент выполняется процесс с номером 4035.

Теперь приостановим наш процесс - состояние T. Перейдите на консоль, на которой запущен ./process и нажмите Ctrl + Z. Вы увидите сообщение Stopped.

  PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME COMMAND
 4035 den        9   0  1320 1320   988 T     0,0  1,0   0:51 process

Теперь попробуем "усыпить" наш процесс. Для этого нужно сначала "убить" его: kill 4035. Затем добавить перед циклом while в сценарии ./process строку sleep 10m, которая означает, что процесс будет спать 10 минут. После этого опять запустите команду ps -a | grep process, чтобы узнать PID процесса, а затем - команду top -p PID. Вы увидите в колонке состояния букву S, что означает, что процесс находится в состоянии ожидания или готовности - попросту говоря "спит".

Мы вплотную подошли к самому интересному - созданию процесса-зомби. Во многих статьях, посвященных процессам, пишется "зомби = не жив, не мертв". А что это означает на самом деле? При завершении процесса должна удаляться его структура из списка процессов. Иногда процесс уже завершился, но его имя еще не удалено из списка процессов. В этом случае процесс становится зомби - его уже нет, но мы его видим в таблице команды top. Такое может произойти, если процесс-потомок (дочерний процесс) завершился раньше, чем этого ожидал процесс-родитель. Сейчас мы напишем программу, порождающую зомби, который будет существовать 8 секунд. Процесс-родитель будет ожидать завершения процесса-потомка через 10 секунд, а процесс-потомок завершить через 2 секунды.


#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <stdio.h>

int main() {
   int pid;
   int status, died;

   pid=fork();
   switch(pid) {
   case -1: printf("can't fork\n");
            exit(-1);
   case 0 : printf("   I'm the child of PID %d\n", getppid());
            printf("   My PID is %d\n", getpid());
	    // Ждем 2 секунды и завершаемся, следующую строку я закомментировал
	    // чтобы зомби "прожил" на 2 секунды больше
//	    sleep(2);
            exit(0);
   default: printf("I'm the parent.\n");
            printf("   My PID is %d\n", getpid());
	    // Ждем завершения дочернего процесса через 10 секунд, а потом убиваем его	    
	    sleep(10);
            if (pid & 1)
               kill(pid,SIGKILL);
            died= wait(&status);
  }
}

Для компиляции данной программы нам нужен компилятор gcc:

gcc -o zombie zombie.c

Для тех, у кого не установлен компилятор, скомпилированная программа доступна отсюда.

После того, как программа будет откомпилирована, запустите ее: ./zombie. Программа выведет следующую информацию:

I'm the parent
  My PID is 1147
  I'm the child of PID 1147
  My PID is 1148

Запомните последний номер и быстро переключайтесь на другую консоль. Затем введите команду top -p 1148

16:04:22  up 2 min,  3 users,  load average: 0,10, 0,10, 0,04
1 processes: 0 sleeping, 0 running, 1 zombie, 0 stopped
CPU states:  4,5% user,  7,6% system,  0,0% nice,  0,0% iowait, 87,8% idle
Mem:   127560k av,   76992k used,   50568k free,       0k shrd,    3872k buff
        24280k active,              19328k inactive
Swap:  152576k av,       0k used,  152576k free                   39704k cached

  PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME COMMAND
 1148 den       17   0     0    0     0 Z     0,0  0,0   0:00 zombie <defunct>

Мы видим, что в списке процессов появился 1 зомби (STAT=Z), который проживет аж 10 секунд.

Мы уже рассмотрели все возможные состояния процессов. Осталось только рассмотреть команду для повышения приоритета процесса - это команда nice. Повысить приоритет команды может только пользователь root, указав соответствующий коэффициент понижения. Для увеличения приоритета нужно указать отрицательный коэффициент, например, nice -5 process

Все ваши вопросы и комментарии рад буду выслушать по адресу dhsilabs@mail.ru. Свои вопросы вы также можете задать на форуме на сайте http://dkws.narod.ru.


Продолжение: Управление процессами в Linux

Процессы. Системные вызовы fork() и exec(). Нити.
Перенаправление ввода/вывода
Команды для управление процессами


Управление процессами в Linux

Денис Колисниченко

Процессы. Системные вызовы fork() и exec(). Нити.
Перенаправление ввода/вывода
Команды для управление процессами
 

Материал этой статьи ни в коем случае не претендует на свою избыточность. Более подробно о процессах вы можете прочитать в книгах, посвященных программированию под UNIX.

Процессы. Системные вызовы fork() и exec(). Нити.

Процесс в Linux (как и в UNIX) - это программа, которая выполняется в отдельном виртуальном адресном пространстве. Когда пользователь регистрируется в системе, автоматически создается процесс, в котором выполняется оболочка (shell), например, /bin/bash.

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

Ядро предоставляет системные вызовы для создания новых процессов и для управления порожденными процессами. Любая программа может начать выполняться только если другой процесс ее запустит или произойдет какое-то прерывание (например, прерывание внешнего устройства).

В связи с развитием SMP (Symmetric Multiprocessor Architectures) в ядро Linux был внедрен механизм нитей или потоков управления (threads). Нить - это процесс, который выполняется в виртуальной памяти, используемой вместе с другими нитями процесса, который обладает отдельной виртуальной памятью.

Если интерпретатору (shell) встречается команда, соответствующая выполняемому файлу, интерпретатор выполняет ее, начиная с точки входа (entry point). Для С-программ entry point - это функция main. Запущенная программа тоже может создать процесс, т.е. запустить какую-то программу и ее выполнение тоже начнется с функции main.

Для создания процессов используются два системных вызова: fork() и exec. fork() создает новое адресное пространство, которое полностью идентично адресному пространству основного процесса. После выполнения этого системного вызова мы получаем два абсолютно одинаковых процесса - основной и порожденный. Функция fork() возвращает 0 в порожденном процессе и PID (Process ID - идентификатор порожденного процесса) - в основном. PID - это целое число.
Теперь, когда мы уже создали процесс, мы можем запустить программу с помощью вызова exec. Параметрами функции exec является имя выполняемого файла и, если нужно, параметры, которые будут переданы этой программе. В адресное пространство порожденного с помощью fork() процесса будет загружена новая программа и ее выполнение начнется с точки входа (адрес функции main).

В качестве примера рассмотрим этот фрагмент программы

if (fork()==0) wait(0);
else execl("ls", "ls", 0); /* порожденный процесс */

Теперь рассмотрим более подробно, что же делается при выполнении вызова fork():

  1. Выделяется память для описателя нового процесса в таблице процессов
  2. Назначается идентификатор процесса PID
  3. Создается логическая копия процесса, который выполняет fork() - полное копирование содержимого виртуальной памяти родительского процесса, копирование составляющих ядерного статического и динамического контекстов процесса-предка
  4. Увеличиваются счетчики открытия файлов (порожденный процесс наследует все открытые файлы родительского процесса).
  5. Возвращается PID в точку возврата из системного вызова в родительском процессе и 0 - в процессе-потомке.
Общая схема управления процессами
Каждый процесс может порождать полностью идентичный процесс с помощью fork(). Родительский процесс может дожидаться окончания выполнения всех своих процессов-потомков с помощью системного вызова wait.
В любой момент времени процесс может изменить содержимое своего образа памяти, используя одну из разновидностей вызова exec. Каждый процесс реагирует на сигналы и, естественно, может установить собственную реакцию на сигналы, производимые операционной системой. Приоритет процесса может быть изменен с помощью системного вызова nice.

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

Примеры сигналов:

  1. окончание порожденного процесса (например, из-за системного вызова exit (см. ниже))
  2. возникновение исключительной ситуации
  3. сигналы, поступающие от пользователя при нажатии определенных клавиш.


Установить реакцию на поступление сигнала можно с помощью системного вызова signal
func = signal(snum, function);

snum - номер сигнала, а function - адрес функции, которая должна быть выполнена при поступлении указанного сигнала. Возвращаемое значение - адрес функции, которая будет реагировать на поступление сигнала. Вместо function можно указать ноль или единицу. Если был указан ноль, то при поступлении сигнала snum выполнение процесса будет прервано аналогично вызову exit. Если указать единицу, данный сигнал будет проигнорирован, но это возможно не для всех процессов.

С помощью системного вызова kill можно сгенерировать сигналы и передать их другим процессам.
kill(pid, snum);
где pid - идентификатор процесса, а snum - номер сигнала, который будет передан процессу. Обычно kill используется для того, чтобы принудительно завершить ("убить") процесс.
Pid состоит из идентификатора группы процессов и идентификатора процесса в группе. Если вместо pid указать нуль, то сигнал snum будет направлен всем процессам, относящимся к данной группе (понятие группы процессов аналогично группе пользователей). В одну группу включаются процессы, имеющие общего предка, идентификатор группы процесса можно изменить с помощью системного вызова setpgrp. Если вместо pid указать -1, ядро передаст сигнал всем процессам, идентификатор пользователя которых равен идентификатору текущего выполнения процесса, который посылает сигнал.

Таблица 1. Номера сигналов
 
Номер Название Описание
01 SIGHUP  Освобождение линии (hangup).
02 SIGINT Прерывание (interrupt). 
03 SIGQUIT Выход (quit). 
04 SIGILL Некорректная команда (illegal instruction). Не переустанавливается при перехвате. 
05 SIGTRAP Трассировочное прерывание (trace trap). Не переустанавливается при перехвате.
06 SIGIOT или SIGABRT Машинная команда IOT. 
07 SIGEMT Машинная команда EMT. 
08 SIGFPE Исключительная ситуация при выполнении операции с вещественными числами (floating-point exception)
09 SIGKILL Уничтожение процесса (kill). Не перехватывается и не игнорируется.
10 SIGBUS Ошибка шины (bus error).
11 SIGSEGV Некорректное обращение к сегменту памяти (segmentation violation).
12 SIGSYS Некорректный параметр системного вызова (bad argument to system call).
13 SIGPIPE Запись в канал, из которого некому читать (write on a pipe with no one to read it).
14 SIGALRM Будильник 
15 SIGTERM  Программный сигнал завершения
16 SIGUSR1 Определяемый пользователем сигнал 1
17 SIGUSR2 Определяемый пользователем сигнал 2 
18 SIGCLD Завершение порожденного процесса (death of a child).
19 SIGPWR Ошибка питания
22 Регистрация выборочного события

Сигналы (точнее их номера) описаны в файле singnal.h

Для нормального завершение процесса используется вызов
exit(status);
где status - это целое число, возвращаемое процессу-предку для его информирования о причинах завершения процесса-потомка.
Вызов exit может задаваться в любой точке программы, но может быть и неявным, например при выходе из функции main (при программировании на C) оператор return 0 будет воспринят как системный вызов exit(0);
 

Перенаправление ввода/вывода

Практически все операционные системы обладают механизмом перенаправления ввода/вывода. Linux не является исключением из этого правила. Обычно программы вводят текстовые данные с консоли (терминала) и выводят данные на консоль. При вводе под консолью подразумевается клавиатура, а при выводе - дисплей терминала. Клавиатура и дисплей - это, соответственно, стандартный ввод и вывод (stdin и stdout). Любой ввод/вывод можно интерпретировать как ввод из некоторого файла и вывод в файл. Работа с файлами производится через их дескрипторы. Для организации ввода/вывода в UNIX используются три файла: stdin (дескриптор 1), stdout (2) и stderr(3).

Символ > используется для перенаправления стандартного вывода в файл.
Пример:
$ cat > newfile.txt Стандартный ввод команды cat будет перенаправлен в файл newfile.txt, который будет создан после выполнения этой команды. Если файл с этим именем уже существует, то он будет перезаписан. Нажатие Ctrl + D остановит перенаправление и прерывает выполнение команды cat.

Символ < используется для переназначения стандартного ввода команды. Например, при выполнении команды cat < file.txt в качестве стандартного ввода будет использован файл file.txt, а не клавиатура.

Символ >> используется для присоединения данных в конец файла (append) стандартного вывода команды. Например, в отличие от случая с символом >, выполнение команды cat >> newfile.txt не перезапишет файл в случае его существования, а добавит данные в его конец.

Символ | используется для перенаправления стандартного вывода одной программы на стандартный ввод другой. Напрмер, ps -ax | grep httpd.

Команды для управления процессами

Команда ps

Предназначена для вывода информации о выполняемых процессах. Данная команда имеет много параметров, о которых вы можете прочитать в руководстве (man ps). Здесь я опишу лишь наиболее часто используемые мной:
Параметр Описание
-a отобразить все процессы, связанных с терминалом (отображаются процессы всех пользователей)
-e отобразить все процессы
-t список терминалов отобразить процессы, связанные с терминалами
-u идентификаторы пользователей отобразить процессы, связанные с данными идентификаторыми
-g идентификаторы групп отобразить процессы, связанные с данными идентификаторыми групп
-x отобразить все процессы, не связанные с терминалом

Например, после ввода команды ps -a вы увидите примерно следующее:



  PID TTY          TIME CMD
 1007 tty1     00:00:00 bash
 1036 tty2     00:00:00 bash
 1424 tty1     00:00:02 mc
 1447 pts/0    00:00:02 mpg123
 2309 tty2     00:00:00 ps

Для вывода информации о конкретном процессе мы можем воспользоваться командой:


# ps -ax | grep httpd
 698 ?        S      0:01 httpd -DHAVE_PHP4 -DHAVE_PROXY -DHAVE_ACCESS -DHAVE_A
 1261 ?       S      0:00 httpd -DHAVE_PHP4 -DHAVE_PROXY -DHAVE_ACCESS -DHAVE_A
 1262 ?       S      0:00 httpd -DHAVE_PHP4 -DHAVE_PROXY -DHAVE_ACCESS -DHAVE_A
 1263 ?       S      0:00 httpd -DHAVE_PHP4 -DHAVE_PROXY -DHAVE_ACCESS -DHAVE_A
 1264 ?       S      0:00 httpd -DHAVE_PHP4 -DHAVE_PROXY -DHAVE_ACCESS -DHAVE_A
 1268 ?       S      0:00 httpd -DHAVE_PHP4 -DHAVE_PROXY -DHAVE_ACCESS -DHAVE_A
 1269 ?       S      0:00 httpd -DHAVE_PHP4 -DHAVE_PROXY -DHAVE_ACCESS -DHAVE_A
 1270 ?       S      0:00 httpd -DHAVE_PHP4 -DHAVE_PROXY -DHAVE_ACCESS -DHAVE_A
 1271 ?       S      0:00 httpd -DHAVE_PHP4 -DHAVE_PROXY -DHAVE_ACCESS -DHAVE_A
 1272 ?       S      0:00 httpd -DHAVE_PHP4 -DHAVE_PROXY -DHAVE_ACCESS -DHAVE_A
 1273 ?       S      0:00 httpd -DHAVE_PHP4 -DHAVE_PROXY -DHAVE_ACCESS -DHAVE_A
 1280 ?       S      0:00 httpd -DHAVE_PHP4 -DHAVE_PROXY -DHAVE_ACCESS -DHAVE_A

В приведенном выше примере используется перенаправление ввода вывода между программами ps и grep, и как результат получаем информацию обо всех процессах содержащих в строке запуска "httpd". Данную команду (ps -ax | grep httpd) я написал только лишь в демонстрационных целях - гораздо проще использовать параметр -С программы ps вместо перенаправления ввода вывода и параметр -e вместо -ax.

Программа top

Предназначена для вывода информации о процессах в реальном времени. Процессы сортируются по максимальному занимаемому процессорному времени, но вы можете изменить порядок сортировки (см. man top). Программа также сообщает о свободных системных ресурсах.



# top
7:49pm  up 5 min,  2 users,  load average: 0.03, 0.20, 0.11
56 processes: 55 sleeping, 1 running, 0 zombie, 0 stopped
CPU states:  7.6% user,  9.8% system,  0.0% nice, 82.5% idle
Mem:   130660K av,   94652K used,   36008K free,       0K shrd,    5220K buff
Swap:   72256K av,       0K used,   72256K free                   60704K cached
PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME COMMAND
1067 root      14   0   892  892   680 R    2.8  0.6   0:00 top
  1 root       0   0    468  468   404 S    0.0  0.3   0:06 init
  2 root       0   0     0    0     0 SW    0.0  0.0   0:00 kflushd
  3 root       0   0     0    0     0 SW    0.0  0.0   0:00 kupdate
  4 root       0   0     0    0     0 SW    0.0  0.0   0:00 kswapd
  5 root     -20 -20     0    0     0 SW<   0.0  0.0   0:00 mdrecoveryd

Просмотреть информацию об оперативной памяти вы можете с помощью команды free, а о дисковой - df. Информация о зарегистрированных в системе пользователей доступна по команде w.

Изменение приоритета процесса - команда nice

nice [-коэффициент понижения] команда [аргумент]

Команда nice выполняет указанную команду с пониженным приоритетом, коэффициент понижения указывается в диапазоне 1..19 (по умолчанию он равен 10). Суперпользователь может повышать приоритет команды, для этого нужно указать отрицательный коэффициент, например --10. Если указать коэффициент больше 19, то он будет рассматриваться как 19.

nohup - игнорирование сигналов прерывания

nohup команда [аргумент]

nohup выполняет запуск команды в режиме игнорирования сигналов. Не игнорируются только сигналы SIGHUP и SIGQUIT.

kill - принудительное завершение процесса

kill [-номер сигнала] PID

где PID - идентификатор процесса, который можно узнать с помощью команды ps.

Команды выполнения процессов в фоновом режиме - jobs, fg, bg

Команда jobs выводит список процессов, которые выполняются в фоновом режиме, fg - переводит процесс в нормальные режим ("на передний план" - foreground), а bg - в фоновый. Запустить программу в фоновом режиме можно с помощью конструкции