Запуск процессов и управление вводом-выводом



Лабораторная работа №12

Изучение процессов в ОС Unix

Цель: получить представление об иерархии процессов операционной системы Unix и изучить возможности управления работой процессов.

Общие положения

Концепция процесса в UNIX

Стандарты UNIX, а именно IEEE Std 1003.1, 2004 Edition, определяют процесс как «адресное пространство с одним или несколькими потоками, выполняющимися в нем, и системные ресурсы, необходимые этим потокам». Процессом можно  считать любую выполняющуюся программу. Процесс состоит из программного кода, данных, переменных (занимающих системную память), открытых файлов (файловых дескрипторов) и окружения. Обычно в системе UNIX процессы совместно используют код и системные библиотеки, так что в любой момент времени в памяти находится только одна копия программного кода.

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

Рисунок 1- Состояния процесса в UNIX

Вывод командой ps столбца STAT предоставляет коды текущего состояния процесса.

Таблица 1.

Код STAT Описание
S Спящий. Обычно ждет появления события, такого как сигнал или активизация ввода
R Выполняющийся. Строго говоря "работоспособный", т.е. в очереди на выполнение, либо выполняющийся, либо готовый к выполнению
D Непрерывно спящий (ожидающий). Обычно ждущий завершения ввода или вывода
T Остановленный. Обычно остановленный системой управления заданиями командной оболочки или находящийся под контролем отладчика
Z Умерший или процесс-зомби
N Задача с низким приоритетом, "nice"
S Ведущий процесс сеанса
+ Процесс в группе фоновых процессов
l Многопотоковый процесс
< Задача с высоким приоритетом

В операционных системах Linux и UNIX используется система приоритетов, всего 40 уровней, начиная с -20 (наивысший приоритет) и заканчивая 19 (низший приоритет).

Процессы, запущенные обычными пользователями, обычно имеют приоритет 0.

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

Команда ps может показать приоритет процесса (например, значение nice или NI) с помощью опции -l.

Команда nice показывает приоритет по умолчанию.

Процессы загрузки системы

С запуска процесса init начинается загрузка самой системы. Во времена молодости в этом месте никаких подводных камней не наблюдалось. Если ядро содержало подпрограммы для работы со всеми необходимыми устройствами (так называемые "драйверы"), оно загружалось и запускало init. Если ядру недоставало каких-то важных драйверов (например, поддержки дискового массива) - оно не загружалось. Из положения выходили просто: в ядро старались включить как можно больше драйверов. Такое ядро называлось базовым (generic) и имело довольно внушительный размер. Загрузив систему с базовым ядром, администратор обычно пересобирал его: выбрасывал из специального файла-профиля драйверы всех отсутствующих в системе устройств, быть может, добавлял новые (те, что не нужны для загрузки, но необходимы для работы, например, звуковые) и компилировал из исходных текстов новое, профильное ядро.

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

Просмотреть список загруженных модулей можно командой lsmod, а подгрузить модуль в память, добавив его к ядру, и удалить его оттуда - командами insmod и rmmod соответственно.

Если в параметрах не указано иное, ядро считает, чтоinit называется /sbin/init. В стартовом виртуальном диске это обычно некоторый простейший сценарий, а в полноценной системе у initдругая задача: он запускает все процессы. Если процессы запускает не он сам, то это делают его потомки, так что все процессы Unix, кроме ядерных, происходят от init.

Полноценно загруженная Unix-система - не только login на виртуальной консоли. Системе есть чем заняться и помимо идентификации пользователей. Даже если компьютер не работает WWW-, FTP- или почтовым сервером для "внешнего мира", себе самой и своим пользователям система предоставляет множество услуг: отсылка заданий на печать и обеспечение их очереди, запуск заданий по расписанию, проверка целостности и т.п. Набор утилит и системных программ, предназначенных для предоставления таких услуг, принято называть подсистемами или службами.

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

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

В ранних версиях UNIX все, что нужно было запускать при старте системы, вписывалось в файл inittab. Было довольно удобно в одном файле указывать, какие именно демоны должны работать в системе, и в каком порядке их запускать. Само поведение демона при запуске явно рассчитано на использование в inittab по методу "wait": классический демон запускается интерактивно, проверяя правильность конфигурационных файлов и прочие условия работы, а затем самостоятельно уходит в фон (делая fork() и завершая родительский процесс). Таким образом, initждет, пока демон работает интерактивно, а когда служба, возглавляемая этим демоном, готова к работе, переходит к следующей строке inittab. Однако часто бывает так, что автор демона не знает, какие именно условия разработчики той или иной версии Unix сочтут пригодными для запуска. Для этого ими создается стартовый сценарий, в котором запрограммирована логика запуска и останова службы.

Стартовый сценарий - программа (обычно написанная на shell), управляющая включением или выключением какого-нибудь свойства системы. Это может быть запуск и остановка HTTP-сервера, активизация и деактивизация сетевых настроек, загрузка модулей и настройка звуковой подсистемы и т.п. Простейший стартовый сценарий обязан принимать один параметр, значение которого может быть словом "start" для запуска (включения) и "stop" для остановки (выключения). Если в определенном дистрибутиве Unix принято решение, что стартовые сценарии должны понимать и другие параметры, например "restart" (обычно "stop"+"start", но не всегда) и "status" (для опроса состояния), это требование распространяется на все стартовые сценарии. Единообразие позволяет, например, без труда запускать и останавливать демоны, не выясняя, каков PID останавливаемого процесса и какой именно сигнал ему следует послать.

Все стартовые сценарии служб, которыми может воспользоваться система, принято хранить в каталоге /etc/rc.d/init.d(в некоторых дистрибутивах, для совместимости со старыми версиями UNIX, используется /etc/init.d, иногда это просто символьная ссылка на /etc/rc.d/init.d).

Запуск процессов и управление вводом-выводом

Каждый процесс (кроме системных) является результатом запуска программы, хранящейся в файле на диске. Для запуска процесса следует ввести путь к запускаемому файлу (относительный или абсолютный) в командной строке shell. Если путь не указан, shell будет искать программу, последовательно проверяя каталоги, указанные в переменной окружения PATH. Найдя файл (файл должен иметь права на запуск), shell проверяет его формат. Если файл является двоичным исполнимым файлом, то он запускается. Если файл - текстовый, то анализируется его первая строка, которая должна содержать путь к интерпретатору программы в виде:

#!/usr/bin/sh

или

#!/usr/local/bin/perl –w

В этом случае shell запускает указанный интерпретатор и передает ему имя текстового файла для исполнения. Если строка с указанием интерпретатора не найдена, то shell запускает свою копию, которая пытается исполнить файл как последовательность команд командной строки.

 

Запуск в фоновом режиме

Если сама программа не предусматривает иное, процесс запускается в интерактивном режиме, т.е. shell ожидает завершения процесса, прежде чем вернуть приглашение командной строки. Для запуска процесса в фоновом режиме, командную строку следует завершить символом '&' (амперсанд).

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

Сложнее обстоит дело, если процесс, запущенный в фоновом режиме пытается считать данные со стандартного ввода. В этом случае, если shell поддерживает управление заданиями, то процесс будет остановлен по сигналу SIGTTIN и будет возобновлен после того, как пользователь переведет его в интерактивный режим.

Запуск в режиме демона

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

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

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

В системе по-умолчанию всегда открыты три "файла" – stdin (клавиатура), stdout (экран) и stderr (вывод сообщений об ошибках на экран). Эти, и любые другие открытые файлы, могут быть перенапрвлены. В данном случае, термин "перенаправление" означает получить вывод из файла, команды, программы, сценария или даже отдельного блока в сценарии и передать его на вход в другой файл, команду, программу или сценарий.

С каждым открытым файлом связан дескриптор файла. Дескрипторы файлов stdin, stdout и stderr -- 0, 1 и 2, соответственно. При открытии дополнительных файлов, дескрипторы с 3 по 9 остаются незанятыми. Иногда дополнительные дескрипторы могут сослужить неплохую службу, временно сохраняя в себе ссылку на stdin, stdout или stderr. Это упрощает возврат дескрипторов в нормальное состояние после сложных манипуляций с перенаправлением и перестановками.

Команда перенаправления вывода Описание
COMMAND_OUTPUT > Перенаправление stdout (вывода) в файл. Если файл отсутствовал, то он создется, иначе -- перезаписывается.
ls -lR > dir-tree.list Создает файл, содержащий список дерева каталогов
: > filename Операция > усекает файл "filename" до нулевой длины. Если до выполнения операции файла не существовало, то создается новый файл с нулевой длиной. Символ : выступает здесь в роли место заполнителя, не выводя ничего.
> filename тот же результат, что и выше -- ": >", но этот вариант неработоспособен в некоторых командных оболочках.
COMMAND_OUTPUT >> Перенаправление stdout (вывода) в файл. Создает новый файл, если он отсутствовал, иначе -- дописывает в конец файла.
1>filename Перенаправление вывода (stdout) в файл "filename".
1>>filename Перенаправление вывода (stdout) в файл "filename", файл открывается в режиме добавления.
2>filename Перенаправление stderr в файл "filename".
2>>filename Перенаправление stderr в файл "filename", файл открывается в режиме добавления.
&>filename Перенаправление stdout и stderr в файл "filename".
2>&1 Перенаправляется stderr на stdout. Сообщения об ошибках передаются туда же, куда и стандартный вывод.

Допускается перенаправление нескольких потоков в один файл.

ls -yz >> command.log 2>&1

 

Сообщение о неверной опции "yz" в команде "ls" будет записано в файл "command.log", поскольку stderr перенаправлен в файл.

 

Команда

 

 cat /dev/null>file

 

обнуляет файл file (содержимое пустого по определению файла /dev/null записывается в файл file).

 


Дата добавления: 2018-04-05; просмотров: 412; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!