Украшения. Аксессуары. Дизайн ногтей. Цвета. Нанесение. Ногти

Ubuntu какие процессы запущены. Все, что вам нужно знать о процессах в Linux

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

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

Каждый запущенный процесс в ОС Linux может породить дополнительные процессы. Процесс, запустивший новый процесс называется родительским процессом. Новый процесс по отношению к создавшему его процессу называется дочерним.

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

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

* Идентификатор процесса (PID) . Каждый процесс в системе имеет уникальный идентификатор. Каждый новый запущенный процесс получает номер на единицу больше предыдущего.

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

* Реальный и эффективный идентификаторы пользователя (UID,EUID) и группы (GID, EGID) . Данные атрибуты процесса говорят о его принадлежности к конкретному пользователю и группе. Реальные идентификаторы совпадают с идентификаторами пользователя, который запустил процесс, и группы, к которой он принадлежит. Эффективные - от чьего имени был запущен процесс. Права доступа процесса к ресурсам ОС Linux эффективными идентификаторами. Если на исполняемом файле программы установлен специальный бит SGID или SUID, то процесс данной программы будет обладать правами доступа владельца исполняемого файла.
Для управления процессом (например, kill) используются реальные идентификаторы. Все идентификаторы передаются от родительского процесса к дочернему.
Для просмотра данных атрибутов можно воспользоваться командой , задав желаемый формат отображения колонок.

* Приоритет или динамический приоритет (priority) и относительный или статический (nice) приоритет процесса .
Статический приоритет или nice-приоритет лежит в диапазоне от -20 до 19, по умолчанию используется значение 0. Значение –20 соответствует наиболее высокому приоритету, nice-приоритет не изменяется планировщиком, он наследуется от родителя или его указывает пользователь. Динамический приоритет используется планировщиком для планирования выполнения процессов. Этот приоритет хранится в поле prio структуры task_struct процесса. Динамический приоритет вычисляется исходя из значения параметра пicе для данной задачи путем вычисления надбавки или штрафа, в зависимости от интерактивности задачи. Пользователь имеет возможность изменять только статический приоритет процесса. При этом повышать приоритет может только root. В ОС Linux существуют две команды управления приоритетом процессов: nice и renice.

* Состояние процесса. В ОС Linux каждый процесс обязательно находится в одном из перечисленных ниже состояний и может быть переведен из одного состояния в другое системой или командами пользователя. Различают следующее состояния процессов:

TASK_RUNNING - процесс готов к выполнению или выполняется (runnable). Обозначается символом R.

TASK_INTERRUPTIBLE - ожидающий процесс (sleeping). Данное состояние означает, что процесс инициализировал выполнение
какой-либо системной операции и ожидает ее завершения. К таким операциям относятся ввод/вывод, завершение дочернего процесса
и т.д. Процессы с таким состоянием обозначаются символом S.

TASK_STOPPED - выполнение процесса остановлено (stopping). Любой процесс можно остановить. Это может делать как система,
так и пользователь. Состояние такого процесса обозначается символом Т.

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

TASK_UNINTERRUPTIBLE -непрерываемый процесс (uninterruptible). Процессы в данном состоянии ожидают завершения операции
ввода - вывода с прямым доступом в память. Такой процесс нельзя завершить, пока не завершится операция ввода/вывода.
Процессы с таким состоянием обозначаются символом D. Состояние аналогично TASK_INTERRUPTIBLE, за исключением того, что процесс
не возобновляет выполнение при получении сигнала. Используется в случае, когда процесс должен ожидать беспрерывно или
когда ожидается, что некоторое событие может возникать достаточно часто. Так как задача в этом состоянии не отвечает
на сигналы, TASK_UNINTERRUPTIBLE используется менее часто, чем TASK_INTERRUPTIBLE.

Типы процессов В Linux процессы делятся на три типа:

  • Системные процессы - являются частью ядра и всегда расположены в оперативной памяти. Системные процессы не имеют соответствующих им программ в виде исполняемых файлов и запускаются при инициализации ядра системы. Выполняемые инструкции и данные этих процессов находятся в ядре системы, таким образом, они могут вызывать функции и обращаться к данным, недоступным для остальных процессов. Системными процессами, например, являются: shed (диспетчер свопинга), vhand (диспетчер страничного замещения), kmadaemon (диспетчер памяти ядра).
  • Демоны - это неинтерактивные процессы, которые запускаются обычным образом - путем загрузки в память соответствующих им программ (исполняемых файлов), и выполняются в фоновом режиме. Обычно демоны запускаются при инициализации системы (но после инициализации ядра) и обеспечивают работу различных подсистем: системы терминального доступа, системы печати, с истемы сетевого доступа и сетевых услуг, почтовый сервер, dhcp-сервер и т. п. Демоны не связаны ни с одним пользовательским сеансом работы и не могут непосредственно управляться пользователем. Большую часть времени демоны ожидают пока тот или иной процесс запросит определенную услугу, например, доступ к файловому архиву или печать документа.
  • Прикладные (пользовательские) процессы . К прикладным процессам относятся все остальные процессы, выполняющиеся в системе. Как правило, это процессы, порожденные в рамках пользовательского сеанса работы. Например, команда ls породит соответствующий процесс этого типа. Важнейшим прикладным процессом является командный интерпретатор (shell), который обеспечивает вашу работу в LINUX. Он запускается сразу же после регистрации в системе. Прикладные процессы linux могут выполняться как в интерактивном, так и в фоновом режиме, но в любом случае время их жизни (и выполнения) ограничено сеансом работы пользователя. При выходе из системы все прикладные процессы будут уничтожены.

Иерархия процессов

В Linux реализована четкая иерархия процессов в системе. Каждый процесс в системе имеет всего одного родителя и может иметь один или более порожденных процессов.

Рис. 3.1 – Фрагмент иерархии процессов

На последней фазе загрузки ядро монтирует корневую файловую систему и формирует среду выполнения нулевого процесса, создавая пространство процесса, инициализируя нулевую точку входа в таблице процесса и делая корневой каталог текущим для процесса. Когда формирование среды выполнения процесса заканчивается, система исполняется уже в виде нулевого процесса. Нулевой процесс "ветвится", запуская fork прямо из ядра, поскольку сам процесс исполняется в режиме ядра. Код, исполняемый порожденным процессом 1, включает в себя вызов системной функции exec, запускающей на выполнение программу из файла "/etc/init". В отличие от нулевого процесса, который является процессом системного уровня, выполняющимся в режиме ядра, процесс 1 относится к пользовательскому уровню. Обычно процесс 1 именуется процессом init, поскольку он отвечает за инициализацию новых процессов. На самом деле вы можете поместить любую программу в /sbin/init и ядро запустит её как только закончит загружаться. Задачей init"а является запуск всего остального нужным образом.

Init читает файл /etc/inittab, в котором содержатся инструкции для дальнейшей работы. Первой инструкцией, обычно, является запуск скрипта инициализации. В системах, основанных на Debian, скриптом инициализации будет /etc/init.d/rcS, в Red Hat - /etc/rc.d/rc.sysinit. Это то место где происходит проверка и монтирование файловых систем (/etc/fstab), установка часов системного времени, включение своп-раздела, присвоение имени хоста и т.д. Далее будет вызван следующий скрипт, который переведёт нас на "уровень запуска" по умолчанию. Это подразумевает просто некоторый набор демонов, которые должны быть запущены.

Syslogd (/etc/init.d/syslogd) – скрипт, отвечающий за запуск и остановку системного логгера (система журнальной регистрации событий SYSLOG, позволяет записывать системные сообщения в файлы журналов /var/log).

Xined –Демон Интернет-служб, управляет сервисами для интернета. Демон прослушивает сокеты и если в каком-то из них есть сообщение определяет какому сервису принадлежит данный сокет и вызывает соответствующую программу для обработки запроса.

crond – Демон cron отвечает за просмотр файлов crontab и выполнение, внесенных в него команд в указанное время для опредленного пользователя. Програма crontab(1) спілкується з crond через файл cron.update, який повинен знаходитись разом з рештою файлів каталогу crontab, як правило - /var/spool/cron/crontabs.

Последним важным действием init является запуск некоторого количества getty. Mingetty – виртуальные терминалы, назначением которых является слежение за консолями пользователей.

getty запускает программу login – начало сеанса роботы пользователя в системе. Задача login"а – регистрация пользователя в системе. А уже после успешной регистрации чаще всего грузиться командный интерпретатор пользователя (shell), например, bash, вернее после регистрации пользователя грузится программа, указанная для данного пользователя в файле /etc/passwd (в большинстве случаев это bash).

2. Запуск процессов

Существует два пути запуска процессов в зависимости от типа процесса.

Для пользовательских процессов запуск осуществляется в интерактивном режиме путем ввода произвольной команды или запуска произвольного скрипта. Для системных процессов и демонов используются инициализационные скрипты (init-скрипты). Данные скрипты используется процессом init для запусков других процессов при загрузке ОС. Инициализационные скрипты хранятся в каталоге /etc. В данном каталоге существуют вложенные каталоги, именуемые rcO.d - rc6.d, каждый из которых ассоциирован с определенным уровнем выполнения (runlevel). В каждом из этих каталогов находятся символьные ссылки на инициализационные скрипты, непосредственно находящиеся в каталоге /etc/rc.d/init.d .

Следует заметить, что в каталоге /etc/init.d присутствуют жесткие ссылки на скрипты каталога /etc/rc.d/init.d, поэтому при изменении скриптов в этих каталогах измененные данные отображаются одинаково вне зависимости от пути к файлу скрипта.

Просмотр init-скриптов

Bee init-скрипты возможно повторно запускать или останавливать, тем самым управляя статусом сервиса, к которому они принадлежат. Запуск данных скриптов осуществляется из командной строки и имеет следующий синтаксис:

/etc/init.d/script-name start|stoplrestart|condrestart|status|reload

Здесь в качестве script-name используется конкретное имя init-скрипта, а в качестве аргументов могут выступать следующие значения:

* start (Запуск сервиса); * stop (Остановка сервиса); * restart (Остановка и последующий запуск сервиса); * condrestart (Условная остановка и последующий запуск сервиса); * status (Получение статуса состояния сервиса); * reload (Повторное считывание конфигурационного файла сервиса). Например, для условного перезапуска сервиса sshd используется следующая команда: # /etc/init.d/sshd condrestart Stopping sshd: [ ok ] Starting sshd: [ ok ] Условный перезапуск сервиса sshd.

В случае использования аргумента condrestart перезапуск сервиса будет осуществлен только в том случае, если сервис уже работает в системе.

В ОС Linux для управления сервисами, помимо непосредственного обращения к файлу init-скрипта, существует специальная команда service (второй способ), в качестве аргумента которой необходимо указать аргументы аналогичные тем, что используются при непосредственном запуске демонов через init-скрипты:

# service sshd reload Reloading sshd: [ ok ] Использование команды service.

В данном примере осуществляется повторное считывание конфигурационного файла сервиса sshd.

Однако управлять демонами в большинстве случаем может только root.

Команды запуска процессов

Чтобы завершить какой-нибудь процесс, нужно послать ему сигнал с помощью команды kill. Для этого необходимо узнать Pid процесса с помощью команды ps (например, Pid процесса равен 11839) и послать процессу сигнал на завершение, например сигнал SIGKILL:

или kill –SIGKILL 11839

или kill –KILL 11839

Что же такое сигналы?

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

Прежде всего, каждый сигнал имеет собственное имя и номер. Имена всех сигналов начинаются с последовательности SIG. Например, SIGALRM – генерируется, когда таймер, установленной функцией alarm(), отмерит указанный промежуток времени. Linux поддерживает 31 сигнал (номера от 1 до 31).

Сигналы могут порождаться различными условиями:

1. Генерироваться терминалом, при нажатии определенной комбинации клавиш, например, нажатие Ctrl+C генерирует сигнал SIGINT, таким образом можно прервать выполнение программы, вышедшей из-под контроля;

2. Аппаратные ошибки - деление на 0, ошибка доступа к памяти и прочие – также приводят к генерации сигналов. Эти ошибки обычно обнаруживаются аппаратным обеспечением, которое извещает ядро об их появлении. После этого ядро генерирует соответствующий сигнал и передает его процессу, который выполнялся в момент появления ошибки. Например, сигнал SIGSEGV посылается процессу в случае попытки обращения к неверному адресу в памяти.

3. Другим процессом (в том числе и ядром и системным процессом), выполнившим системный вызов передачи сигнала kill();

4. При выполнении команды kill.

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

В случае получения сигнала процесс может запросить ядро выполнить одну из трех реакции на сигнал:

1. Принудительно проигнорировать сигнал (практически любой сигнал может быть проигнорирован, кроме SIGKILL и SIGSTOP).

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

3. Перехватить сигнал (выполнить обработку сигнала, специфицированную пользователем).

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

Задача (job) - это просто рабочая единица командного процессора.

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

  • интерактивное задание (foreground job) - Выполняемое в командном процессоре, занимающее сеанс командного процессора, так что вы не можете выполнить другую команду.
  • фоновое задание (background job) - Выполняемое в командном процессоре, но не занимающее сеанс командного процессора, так что вы можете выполнить другую команду в этом же командном процессоре.
  • приостановить (suspend) - Временно приостановить интерактивный процесс.
  • возобновить (resume) - Вернуться к вьполнению приостановленной задачи.

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

Если вы запустили из командного процессора команду в интерактивном режиме и хотите немедленно прекратить выполнение команды , введите Ctrl-С. Командный процессор воспримет нажатие Ctrl-С как "остановить выполнение текущей задачи немедленно". Поэтому, если вы выводите очень длинный файл (скажем, командой cat) и хотите остановить вывод, нажмите Ctrl-С. На самом деле текущей задаче по нажатию Ctrl-С отправится сигнал SIGINT.

Чтобы прекратить выполнение программы, работающей в фоновом режиме, вы можете перевести ее в интерактивный режим с помощью команды fg и затем нажать Ctrl-С, или использовать команду kill.

В Linux также имеются команды для управления процессами, например kill, pkill, pgrep и killall. Ниже приведено несколько примеров их использования:

$ pgrep -u tecmint top $ kill 2308 $ pgrep -u tecmint top $ pgrep -u tecmint glances $ pkill glancesми $ pgrep -u tecmint glances

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

Обратите внимание, что с их помощью вы можете завршать зависшие приложения, которые тормозят вашу систему.

Отправка сигналов процессу

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

$ kill -l

Для отправки сигналов процессу используются описанные выше команды kill, pkill или pgrep. Однако программа ответит на сигнал, только если она запрограммирована распознавать такой сигнал.

Большинство сигналов предназначены для использования системой или программистами при написании кода. Следующие сигналы могут быть полезны пользователю:

SIGHUP 1 – отправляется процессу при закрытии контролирующего его терминала.
SIGINT 2 – отправляется процессу контролирующим его терминалом, если пользователь прерывает работу процесса клавишами .
SIGQUIT 3 – отправляется процессу, если пользователь посылает сигнал выхода из программы .
SIGKILL 9 – этот сигнал немедленно завершает (убивает) процесс без выполнения любых операций очистки файлов, логов и т.д.
SIGTERM 15 – это сигнал завершения работы программы (он по умоланию отправляется командой kill).
SIGTSTP 20 – отправляется процессу контролирующим его терминалом с запросом на остановку (terminal stop); инициируется при нажатии .

Ниже приведены примеры использования команд kill для завершения работы Firefox при его зависании с использованием PID:

$ pidof firefox $ kill 9 2687 OR $ kill -KILL 2687 OR $ kill -SIGKILL 2687

Для завершения программы с использованием ее названия используются команды pkill или killall:

$ pkill firefox $ killall firefox

Изменение приоритета процесса

В Linux все активные процессы имеют определенное значение приоритета (nice). Процессы с более высоким приоритетом обычно получают больше процессорного времени, чем процессы с более низким приоритетом.

Однако пользователь с привилегиями root может менять приоритет с помощью команд nice и renice.
В выводе команды top столбец NI отображает значения nice для процессов.

Вы можете использовать команду nice, чтобы задать значение nice процесса. Не забывайте, что обычный пользователь может присвоить процессу значение nice от 0 до 20, только если это процесс ему принадлежит.
Отрицательные значения nice может использовать только пользователь root.

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

$ renice +8 2687 $ renice +8 2103

Процесс – это абстракция, используемая для описания выполняющийся программы. Процесс представляет из себя системный объект, посредством которого можно контролировать обращение программы к памяти, центральному процессору и ресурсам ввода-вывода. В операционных системах Linux и Unix системные и пользовательские процессы подчиняются одним и тем же правилам, благодаря чему управление осуществляется с помощью единого набора команд.

Процесс состоит из адресного пространства и набора структур данных, содержащихся внутри ядра. Адресное пространство представляет собой совокупность страниц памяти, которые были выделены ядром для выполнения процесса. В него загружается код и используемые им библиотеки функций, а также переменные, содержимое стеков и различная вспомогательная информация, необходимая ядру для работы процесса. Поскольку в системах UNIX и Linux поддерживается концепция виртуальной памяти, страницы адресного пространства процесса в конкретный момент времени могут находится либо в физической памяти, либо в разделе подкачки, т.е. на диске.

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

  • Таблицу распределения памяти
  • Текущий статус (неактивен, приостановлен, выполняется и т.п.)
  • Приоритет
  • Информацию об используемых ресурсах
  • Информацию о файлах и сетевых портах, открытых процессом
  • Маску сигналов (запись о том, какие сигналы блокируются)
  • Имя владельца процесса

Поток выполнения, обычно именуемой просто потоком, представляет результат разветвления в выполнении процесса. Поток наследует многие атрибуты своего процесса, причем в рамках одного процесса могут выполняться одновременно (параллельно) несколько потоков – такая модель выполнения получила название многопоточности. В старых однопроцессорных системах параллельное выполнение моделируется ядром, но в мультиядерных и многопроцессорных архитектурах потоки могут выполняться одновременно в различных ядрах. Такие многопоточные приложения, как BIND и Apache, извлекают максимальную пользу из мультиядерных систем, поскольку эти приложения могут обрабатывать несколько запросов одновременно.

Атрибуты процесса

Ядро назначает каждому процессу уникальный идентификатор PID . PID – Proccess ID. Большинство команд и системных вызовов, работающих с процессами, требуют указания конкретного идентификатора, чтобы был ясен контекст операции. Идентификаторы присваиваются по порядку по мере создания процессов.

Ни в UNIX, ни в Linux нет системного вызова, который бы инициировал новый процесс для выполнения конкретной программы. Для того, чтобы породить новый процесс, существующий процесс должен клонировать себя сам. Клон может заменить выполняемую программу другой.

В операции клонирования исходный процесс называют родительским, а его клон – дочерним. Помимо собственного идентификатора, каждый дочерний процесс имеет атрибут PPID (Parent Proccess ID), который совпадает с идентификатором породившего его дочернего процесса. Стоит отметить, что PPID – весьма полезная информация, если приходится иметь дело с неизвестными процессами. Отслеживание истоков процесса может облегчить понимание его назначения и значимости.

Когда система загружается, ядро самостоятельно запускает несколько процессов. Наиболее важный из них – демон init , идентификатор которого всегда равен 1. Демон init отвечает за выполнение сценариев запуска системы. Все процесса, кроме тех, что создаются ядром, являются потомками демона init.

UID (User ID) – это идентификатор пользователя, создавшего данный процесс. Менять атрибуты процесса могут только его создатель (владелец) и суперпользователь. EUID (Effective User ID) – это текущий пользовательский идентификатор процесса, предназначенный для того, чтобы определить, к каким ресурсам и файлам у процесса есть доступ в данный момент. У большинства программ значения UID и EUID одинаковы. Исключение составляют программы, у которых установлен бит смены идентификатора пользователя (setuid).

GID (Group ID) – это идентификатор группы, к которому принадлежит владелец процесса. Текущий идентификатор группы (EGID) связан с атрибутом GID так же, как и значение EUID связано с UID.

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

Жизненный цикл процесса

Создание процесса – это переход процесса из состояния “Новый” в состояние “Готов”. В момент создания процесса операционная система подготавливает структуру данных для него. Новому процессу присваивается собственный PID, и учет ресурсов ведется независимо от предка. Тот факт, что процесс существует – еще не дает ему права на использование ресурсов центрального процессора.

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

Из состояния “Запущен” есть два пути:

  1. Таймаут – процесс поработал и освободил ресурсы процессора (перешел в очередь)
  2. Ожидание – процесс переведен в режим ожидания, где ждет некоего сигнала

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

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

После того как процесс завершился – он уничтожается.

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

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

Работа с процессами в Linux

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

user@ubuntu$ ps aux

Ключ a используется для вывода всех процессов, ключ x – отображает процессы, отсоединенные от терминала, ключ u – обеспечивает фильтрование по имени или идентификатору пользователя, который запустил программу.

Значение столбцов при выводе команды ps aux :

  1. USER – имя владельца процесса
  2. PID – идентификатор процесса
  3. %CPU – доля времени центрального процессора, которая тратится на данный процесс (в процентах)
  4. %MEM – часть реальной памяти, которая тратится на данный процесс (в процентах)
  5. VSZ – виртуальный размер процесса
  6. RSS – количество страниц памяти
  7. TTY – идентификатор управляющего терминала
  8. STAT – текущий статус процесса (R-выполняется, D-ожидает записи на диск, S-неактивен, T-приостановлен, Z-зомби)
  9. TIME – количество времени центрального процессора, затраченное на выполнение данного процесса
  10. COMMAND – имя и аргументы команды

Ниже в сокращенном виде показаны результаты работы команды ps lax. Обратите внимание на дополнительные поля PPID (идентификатор родительского процесса), NI (фактор уступчивости), WCHAN (ресурс, которого ожидает процесс).

NI по сути отображает приоритет процесса. Чем ниже значение – тем приоритетней он будет выполняться процессором. Значение варьируются от -20 до 20.

Очень удобно искать идентификатор процесса с помощью связки команд ps и grep . PS выводит список процессов, после чего передает управление команде grep, которая в свою очередь выделяет из списка искомый процесс. Пример: найдем PID для процесса cron.

Как видно PID для процесса cron равен 879.

Команда ps позволяет сделать только разовый “снимок” системы. Для динамического отслеживания процессов используют команду top .

Наиболее активные процессы находятся вверху. Команда top отображает также статистику по статусам процессов, объем используемых ресурсов ЦПУ и оперативной памяти.

Сигналы – это запросы на прерывания, реализуемые на уровне процессов.

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

Дамп памяти – это файл, содержащий образ памяти процесса

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

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

Определено свыше тридцати разных сигналов, и они находят самое разное применение. Самые распространенные из них:

  1. KILL – безусловное завершение процесса на уровне ядра
  2. STOP – приостанавливает выполнение процесса
  3. CONT – возобновляет выполнение процесса
  4. TSTP – генерируется при нажатии CTRL + Z, приостанавливает процесс пользователем
  5. TERM – запрос на завершение программы (процесс осуществляет очистку и нормально завершается)
  6. QUIT – то же самое, что и TERM + создается дамп памяти
  7. HUP – команда сброса
  8. BUS – ошибка на шине (указывает на неправильное обращение к памяти)
  9. SEGV – ошибка на сегментации (указывает на неправильное обращение к памяти)

Сигналы KILL и STOP нельзя ни перехватить, ни заблокировать, ни проигнорировать.

Команда kill используется для отправки сигналов процессу. Kill имеет следующий синтаксис:

user@ubuntu$ kill [-сигнал] PID

Для примера уничтожим процесс cron. Ранее мы выяснили, что его PID = 879.

user@ubuntu$ kill -KILL 879

Как видим процесс cron убран. Сигналы типа kill надо посылать с правами суперпользователя. Также перед тем, как убивать cron я убрал строчку respawn в конфигурационном файле cron.conf, который находится в папке /etc/init/cron.conf.

Напоследок расскажу про еще одну интересную вещь. Upstart – это система инициализации ОС, которая управляет запуском демонов в течении загрузки системе. Хранятся конфигурационные файлы Upstart в папке /etc/init. Существует несколько команд для работы с Upstart.

user@ubuntu$ status [имя процесса] – статус процесса

user@ubuntu$ start [имя процесса] – запуск процесса

user@ubuntu$ stop [имя процесса] – остановка процесса

user@ubuntu$ restart [имя процесса] – рестарт процесса

Поддержите проект

Друзья, сайт Netcloud каждый день развивается благодаря вашей поддержке. Мы планируем запустить новые рубрики статей, а также некоторые полезные сервисы.

У вас есть возможность поддержать проект и внести любую сумму, которую посчитаете нужной.

В этом отрывке рассмотрены команды управления процессами. Вы научитесь замораживать процессы, размораживать, отправлять в фоновый режим, изменять приоритет, просматривать запущенные процессы и жестоко их убивать. Введено понятие сигналов. Рассмотрены такие команды, как bg, fg, jobs, kill, nohup, nice, renice, ps и top.

Об авторах

Daniel Robbins

Дэниэль Роббинс - основатель сообщества Gentoo и создатель операционной системы Gentoo Linux. Дэниэль проживает в Нью-Мехико со свой женой Мэри и двумя энергичными дочерьми. Он также основатель и глава Funtoo , написал множество технических статей для IBM developerWorks , Intel Developer Services и C/C++ Users Journal.

Chris Houser

Крис Хаусер был сторонником UNIX c 1994 года, когда присоединился к команде администраторов университета Тэйлора (Индиана, США), где получил степень бакалавра в компьютерных науках и математике. После он работал во множестве областей, включая веб-приложения, редактирование видео, драйвера для UNIX и криптографическую защиту. В настоящий момент работает в Sentry Data Systems. Крис также сделал вклад во множество свободных проектов, таких как Gentoo Linux и Clojure, стал соавтором книги The Joy of Clojure .

Aron Griffis

Эйрон Гриффис живет на территории Бостона, где провел последнее десятилетие работая в Hewlett-Packard над такими проектами, как сетевые UNIX-драйвера для Tru64, сертификация безопасности Linux, Xen и KVM виртуализация, и самое последнее - платформа HP ePrint . В свободное от программирования время Эйрон предпочитает размыщлять над проблемами программирования катаясь на своем велосипеде, жонглируя битами, или болея за бостонскую профессиональную бейсбольную команду «Красные Носки».

В сегодняшнем посте расскажу о том, как работают процессы в ОC Linux , а так же как управлять этими самыми процессами , о выполнении процессов в фоне, о повышении/понижении приоритета процессов.

В общем представлении, процесс - это программа, выполняющаяся в оперативной памяти компьютера. Реально, все гораздо сложней.

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

Все новые процессы в Linux порождаются клонированием какого-то уже имеющегося процесса, с помощью вызова системных функций clone(2) и fork(2) (от forking - порождение). У нового (порожденного или дочернего) процесса тоже окружение, что и у родителя, отличается только номер ID процесса (т.н. PID). Жизнь типичного процесса в Linux можно представить следующей схемой:

На которой можно описать пошагово следующие этапы:

  • процесс /bin/bash клонирует себя системным вызовом fork()
  • при этом создается клон /bin/bash с новым PID (идентификатор процесса) и PPID - равный PID родителя
  • Клон выполняет системный вызов exec с указанием на исполняемый файл и заменяет свой код - кодом исполняемого файла (родительский процесс при этом ждет завершения потомка - wait)
    • при этом, если по каком-то причинам, потомок завершил свою работу, а родительский процесс не смог получить об этом сигнал, то данный процесс (потомок) не освобождает занятые структуры ядра и состояние процесса становиться - zombie. О состояниях процесса ниже...

Очень наглядную схему предоставила википедия:

Из вышесказанного может последовать логичный вопрос: если новый процесс - всегда копия существующего, то каким образом в системе берется самый первый из процессов?

Первый процесс в системе запускается при инициализации ядра. Данный процесс называется - init и имеет PID=1. Это прородитель всех процессов в системе.

В каких же состояниях может находиться процесс в Linux?

Каждый запущенный процесс в любой момент времени находится в одном из следующих состояний (которое называют еще статусом процесса):

  • Активен (R=Running) – процесс находится в очереди на выполнение, то есть либо выполняется в данный момент, либо ожидает выделения ему очередного кванта времени центрального процессора.
  • «Спит» (S=Sleeping) – процесс находится в состоянии прерываемого ожидания, то есть ожидает какого-то события, сигнала или освобождения нужного ресурса.
  • Находится в состоянии непрерываемого ожидания (D=Direct) – процесс ожидает определенного («прямого») сигнала от аппаратной части и не реагирует на другие сигналы;
  • Приостановлен (T) – процесс находится в режиме трассировки (обычно такое состояние возникает при отладке программ).
  • «Зомби» (Z=Zombie) – это процесс, выполнение которого завершилось, но относящиеся к нему структуры ядра по каким-то причинам не освобождены. Одной из причин их появления в системе может быть следующая ситуация. Обычно освобождение структур ядра, относящихся к процессу, выполняет процесс-родитель после получения от потомка сигнала о завершении. Но бывают случаи, когда родительский процесс завершается раньше дочернего. Процессы, не имеющие родителя, называются "сиротами ". "Сироты " автоматически усыновляются процессом init , который и принимает сигналы об их завершении. Если процесс-родитель или init по каким-то причинам не может принять сигнал о завершении дочернего процесса, то процесс-потомок превращается в "зомби" и получает статус Z. Процессы-зомби не занимают процессорного времени (т. е. их выполнение прекращается), но соответствующие им структуры ядра не освобождаются. В некотором смысле это «мертвые» процессы. Уничтожение таких процессов - одна из обязанностей системного администратора. Хочу отметить, что появление данных процессов говорит о том, что в системе что-то не в порядке, и скорее всего не в порядке с аппаратной частью, так что берем memtest и MHDD и тестим-тестим. Не исключен вариант и кривого кода программы.

Так же, говоря о процессах в линуксе, можно выделить особый вид процессов - демоны . Данный вид процессов работает в фоне (подобно службам в Windows), без терминала и выполняет задачи для других процессов. Данный вид процессов на серверных системах является основным.

Т.к. в большинстве случаев, демоны в Linux простаивают и ожидают поступления каких-либо данных, соответственно, нужны относительно редко, так что держать их в памяти постоянно загруженными и расходовать на это ресурсы системы нерационально. Для организации работы демонов придуман демон inetd или его более защищенная модификация xinetd (eX tended I nterNET Daemon или расширенный Интернет демон). В функции inetd (Xinetd) можно выделить:

  • установить ограничение на количество запускаемых серверов (служб , демонов)
  • наблюдение за соединениями на определенных портах и обработка входящих запросов
  • ограничение доступа к сервисам на основе ACL (списков контроля доступа)

Все процессы в системе, не важно Linux это или другая ОС, обмениваются между собой какой-либо информацией. Отсюда можно задать вопрос, а как же происходит межПРОЦЕССный обмен?

В ОС LINUX существует несколько видов можпроцессного обмена, а точнее сказать средств межпроцессного взаимодействия (Interprocess Communication - IPC) , которые можно разбить на несколько уровней:

локальный (привязаны к процессору и возможны только в пределах компьютера);

-- каналы

  1. pipe (они же конвейеры, так же неименованные каналы), о них я много рассказывал в прошлом посте, примером можно привести: команда1 | команда2. По сути, pipe использует stdin, stdout и stderr.
  2. Именованные каналы (FIFO: First In First Out). Данный вид канала создаётся с помощью mknod или mkfifo , и два различных процесса могут обратиться к нему по имени. Пример работы с fifo:

в первом терминале (создаем именованный канал в виде файла pipe и из канала направляем данные с помощью конвейера в архиватор):

# mkfifo pipe # ls -l total 0 prw-r--r-- 1 root root 0 Nov 9 19:41 pipe # gzip -9 -c < pipe > out

во втором терминале (отправляем в именованный канал данные):

# cat /path/to/file > pipe

в результате это приведет к сжатию передаваемых данных gzip-ом

-- сигналы

  • с терминала, нажатием специальных клавиш или комбинаций (например, нажатие Ctrl-C генерирует SIGINT, а Ctrl-Z SIGTSTP);
  • ядром системы:
    • при возникновении аппаратных исключений (недопустимых инструкций, нарушениях при обращении в память, системных сбоях и т. п.);
    • ошибочных системных вызовах;
    • для информирования о событиях ввода-вывода;
  • одним процессом другому (или самому себе), с помощью системного вызова kill(), в том числе:
    • из шелла, утилитой /bin/kill .

сигнал - это асинхронное уведомление процесса о каком-либо событии. Когда сигнал послан процессу, операционная система прерывает выполнение процесса. Если процесс установил собственный обработчик сигнала, операционная система запускает этот обработчик, передав ему информацию о сигнале. Если процесс не установил обработчик, то выполняется обработчик по умолчанию.
Все сигналы начинаются на «SIG…» и имеют числовые соответствия, определяемые в заголовочном файле signal.h. Числовые значения сигналов могут меняться от системы к системе, хотя основная их часть имеет в разных системах одни и те же значения. Утилита kill позволяет задавать сигнал как числом, так и символьным обозначением.
Сигналы можно послать следующими способами:

-- разделяемая память

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

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

-- очереди сообщений

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

удаленный;

-- удаленные вызовы процедур (Remote Procedure Calls - RPC)

RPC - разновидность технологий, которая позволяет компьютерным программам вызывать функции или процедуры в другом адресном пространстве (как правило, на удалённых компьютерах). Обычно, реализация RPC технологии включает в себя два компонента: сетевой протокол (чаще TCP и UDP, реже HTTP) для обмена в режиме клиент-сервер и язык сериализации объектов (или структур, для необъектных RPC).

-- сокеты Unix

Сокеты UNIX бывают 2х типов: локальные и сетевые . При использовании локального сокета , ему присваивается UNIX-адрес и просто будет создан специальный файл (файл сокета ) по заданному пути, через который смогут сообщаться любые локальные процессы путём простого чтения/записи из него. Сокеты представляют собой виртуальный объект, который существует, пока на него ссылается хотя бы один из процессов. При использовании сетевого сокета , создается абстрактный объект привязанный к слушающему порту операционной системы и сетевому интерфейсу, ему присваивается INET-адрес , который имеет адрес интерфейса и слушающего порта.

высокоуровневый

  1. Обычно - пакеты программного обеспечения, которые реализуют промежуточный слой между системной платформой и приложением. Эти пакеты предназначены для переноса уже испытанных протоколов коммуникации приложения на более новую архитектуру. Примером можно привести: DIPC, MPI и др. (мне не знакомы, честно говоря)

Итак. Подведем маленький итог:

  • В Linux есть процессы,
  • каждый процесс может запускать подпроцессы (нити),
  • создание нового процесса создается клонированием исходного,
  • прородителем всех процессов в системе является процесс init, запускаемый ядром системы при загрузке.
  • процессы взаимодействуют между собой по средствам можпроцессного взаимодействия:
    • каналы
    • сигналы
    • сокеты
    • разделяемая память
  • каждый процесс обладает свойствами (читай: обладает следующим контекстом):
    • PID - идентификатор процесса
    • PPID - идентификатор процесса, породившего данный
    • UID и GID - идентификаторы прав процесса (соответствует UID и GID пользователя, от которого запущен процесс)
    • приоритет процесса
    • состояние процесса (выполнение, сон и т.п.)
    • так же у процесса есть таблица открытых (используемых) файлов

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

Получение информации о процессе

Перед тем как управлять процессами, нужно научиться получать о процессах необходимую информацию . В Linux существует псевдо procfs , которая в большинстве дистрибутивов монтируется в общую ФС в каталог /proc . У данной файловой системы нет физического места размещения, нет блочного устройства, такое как жесткий диск. Вся информация, хранимая в данном каталоге находится в оперативной памяти компьютера, контролируется ядром ОС и она не предназначена для хранения файлов пользователя. О структуре данного каталога я написал в статье . В этой файловой системе дано достаточно много информации, чтобы узнать о процессах и о системе в целом.

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

Чтобы получить список всех процессов , достаточно ввести команду:

# ps aux

Прокомментируем некоторые интересные моменты. Можно заметить, что некоторые процессы указаны в квадратных скобках – это процессы, которые входят непосредственно в состав ядра и выполняют важные системные задачи, например, такие как управление буферным кэшем и организацией свопинга . С ними лучше не экспериментировать – ничего хорошего из этого не выйдет:). Остальная часть процессов относится к пользовательским.

Какую информацию можно получить по каждому процессу (комментарии к некоторым полям):

  • PID, PPID – идентификатор процесса и его родителя.
  • %CPU – доля процессорного времени, выделенная процессу.
  • %MEM – процент используемой оперативной памяти.
  • VSZ – виртуальный размер процесса.
  • TTY – управляющий терминал.
  • STAT – статус процесса:
    • R – выполняется;
    • S – спит;
    • Z – зомби;
    • < – Повышенный приоритет;
    • + – Находится в интерактивном режиме.
  • START – время запуска.
  • TIME – время исполнения на процессоре.

Команда ps делает моментальный снимок процессов в текущий момент. В отличии от нее, команда top - динамически выводит состояние процессов и их активность в реальном режиме времени.

Пример вывода команды top:

14:32:49 up 35 days, 6:01, 4 users, load average: 0.65, 0.51, 0.49 Tasks: 432 total, 1 running, 431 sleeping, 0 stopped, 0 zombie CPU0: 1.6%us, 3.6%sy, 0.0%ni, 85.3%id, 9.2%wa, 0.0%hi, 0.3%si, 0.0%st CPU1: 0.9%us, 1.9%sy, 0.0%ni, 96.9%id, 0.0%wa, 0.0%hi, 0.3%si, 0.0%st Mem: 1033596K total, 1016644K used, 16952K free, 82928K buffers Swap: 2096376K total, 12632K used, 2083744K free, 478220K cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2788 root 15 -5 0 0 0 S 2.0 0.0 404:43.97 md3_raid1 7961 root 20 0 5964 2528 1684 R 2.0 0.2 0:00.14 top 6629 root 20 0 8612 2884 2096 S 0.7 0.3 0:00.96 dovecot-auth 57 root 15 -5 0 0 0 S 0.3 0.0 4:36.10 kblockd/0 8703 ulogd 20 0 17700 4216 656 S 0.3 0.4 87:23.98 ulogd 11336 ldap 20 0 394M 15M 8292 S 0.3 1.5 5:29.28 slapd 25757 ldap 20 0 394M 15M 8292 S 0.3 1.5 5:11.71 slapd 10991 root 20 0 2188 1004 588 S 0.3 0.1 4:23.33 dovecot 1 root 20 0 1712 516 464 S 0.0 0.0 0:46.17 init 2 root 15 -5 0 0 0 S 0.0 0.0 0:00.00 kthreadd 3 root RT -5 0 0 0 S 0.0 0.0 0:05.92 migration/0 ..... 2960 root 16 -4 1980 520 392 S 0.0 0.1 0:10.04 udevd 2993 dovecot 20 0 4412 1800 1476 S 0.0 0.2 0:00.00 pop3-login 2994 dovecot 20 0 4412 1800 1476 S 0.0 0.2 0:00.02 pop3-login

В верхней части вывода отображается астрономическое время, время, прошедшее с момента запуска системы, число пользователей в системе, число запущенных процессов и число процессов, находящихся в разных состояниях, данные об использовании ЦПУ, памяти и свопа. А далее идет таблица, характеризующая отдельные процессы. Число строк, отображаемых в этой таблице, определяется размером окна: сколько строк помещается, столько и выводится.

Содержимое окна обновляется каждые 5 секунд. Список процессов может быть отсортирован по используемому времени ЦПУ (по умолчанию), по использованию памяти, по PID, по времени исполнения. Переключать режимы отображения можно с помощью следующих клавиатурных команд:

С помощью команды можно завершить некоторый процесс (его PID будет запрошен), а с помощью команды можно переопределить значение nice для некоторого процесса.

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

Итак, теперь об управлении процессами .

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

Каждому процессу при запуске устанавливается определенный приоритет , который имеет значение от -20 до +20, где +20 - самый низкий. Приоритет нового процесса равен приоритету процесса-родителя. Для изменения приоритета запускаемой программы существует утилита nice . Пример ее использования:

# nice [- adnice] command

где adnice - значение (от –20 до +19), добавляемое к значению nice процесса-родителя. Отрицательные значения может устанавливать только суперпользователь. Если опция adnice не задана, то по умолчанию для процесса-потомка устанавливается значение nice, увеличенное на 10 по сравнению со значением nice родительского процесса.

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

Как я уже писал, одним из средств управления процессами являются сигналы . Некоторые сигналы можно сгенерировать с помощью определенных комбинаций клавиш, но такие комбинации существуют не для всех сигналов. Зато имеется команда kill , которая позволяет послать заданному процессу (указав его PID) любой сигнал:

# kill [-SIG] PID

где SIG - это номер сигнала или наименование сигнала, причем если указание сигнала опущено, то посылается сигнал 15 (SIGTERM - программное завершение процесса). Часто используется сигнал 9 (KILL ), с помощью которого суперпользователь может завершить любой процесс. Но сигнал этот очень "грубый", если можно так выразиться, потому что он просто «убивает» процесс, не давая ему времени на корректное сохранение всех обработанных данных. Поэтому в большинстве случаев рекомендуется использовать сигналы TERM или QUIT , которые завершают процесс более "мягко". Если процессу необходимо как-то по-особенному реагировать на сигнал, он может зарегистрировать обработчик , а если обработчика нет, за него отреагирует система.

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

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

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

В имеются две встроенные команды, которые служат для перевода процессов на передний план или возврата их в фоновый режим. Команда fg переводит указанный в аргументе процесс на передний план, а команда bg - переводит процесс в фоновый режим. Одной командой bg можно перевести в фоновый режим сразу несколько процессов, а вот возвращать их на передний план необходимо по одному. Аргументами команд fg и bg могут являться только номера заданий, запущенных из текущего экземпляра shell. Возможные значения заданий можно увидеть, выполнив команду jobs .

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

# nohup команда &

Запущенный таким образом процесс будет игнорировать посылаемые ему сигналы (не игнорируются только сигналы SIGHUP и SIGQUIT ). Хочу так же выделить команду pstree , которая показывает дерево процессов. Очень наглядно, кстати.