Пример. Бесконечная (циклическая) процедура выводит каждые пять секунд сообщение в указанный файл fil.
while true
do
echo “текст_сообщения”>fil
sleep 5
done
Примечание: вместо файла (или экрана) может быть использовано фиктивное устройство /dev/null (например для отладки процедуры).
Примечание: в процедуре реализуется бесконечный цикл. Для ограничения числа циклов надо предусмотреть счетчик циклов (см. выше) или пркратить выполнение процесса процедуры с помощью команды управления процессами - $kill (см. ниже).
exit [n] - прекращение выполнения процедуры с кодом завершения [n] или с кодом завершения последней выполненной команды.
В качестве “n” можно использовать любое число, например, для идентификации выхода из сложной процедуры, имеющей несколько причин завершения выполнения.
Тема 26. УПРАВЛЕНИЕ ПРОЦЕССАМИ В UNIX
UNIX - многопользовательская многозадачная операционная система. Концепция процесса является базовой для архитектуры ОС. Процесс строится для каждой прикладной (например sh-процедуры и системной задачи (например - утилиты) с помощью системного вызова fork. Является единицей вычислительной работы и потребления ресурсов. В процессе жизни в системе, процесс непосредственно управляется специальными системными вызовами, которые обеспечивают его построение - передачу управления - завершение:
fork - exec - exit совокупность этих переключений
состояний процесса определяют время
существования процесса.
В общем случае активныйпроцесс (выполняемая задача) может находиться в одном из шести состояний (в Linux):
· ожидание процессора в очереди
· выполнение на процессоре в течение выделенного кванта времени
· ожидание освобождения ресурса (например – устройства)
|
· приостановлен специальным сигналом
· завершился, но его дескриптор еще в оперативной памяти ядра ОС
· процесс свопирован на внешнюю память.
В ОП в активном состоянии находится несколько процессов - до 30000..Каждому процессу выделяется виртуальная память практически без ограничений (за счет страничной организации).
При выполнении любого вычислительного задания прикладные и системные процессы ядра должны взаимодействовать между собой. Это необходимо для обмена данными, для передачи управляющей информации при использовании системных ресурсов, для синхронизации или управления последовательностью выполнения процессов и т.п.. Для этих целей служат специальные системные программы, встроенные в оболочку и поддерживающие следующие механизмы взаимодействия процессов:
- программы-сокеты - для обмена данными;
- программные каналы для обмена данными между утилитами (см. выше);
- асинхронные сигналы – ключевые слова, передаваемые от одного процесса к другому, напрмер, для завершения выполнения процесса или для получения информации о свершении некоторых событий в системе (сигнал от таймера, ошибка при передачи данных на устройство, попытка выполнения несуществующей команды и пр.);
- семафоры – синхронизация выполнения процессов посредством установки значений бит-"флагов" специальных системных переменных;
- совместно используемая общая область физической памяти.
Перечисленные механизмы использует как сама ОС (write,mail и пр.), так и прикладные программы с помощью команд управления процессами или системных вызоваов.
|
Роассмотрим создание и работу процессов на примере процедуры. Так как sh-процедура - исполняемый файл то процесс его выполнения обеспечивается в ОС обычными механизмами построения и управления процессами. Для каждой sh-процедуры строится свой процесс со своим дескриптором - порожденный процесс. В дескрипторе процесса хранится информация, необходимая ядру для управления процессом. Дескриторы хранятся в адресном пространствя ядра ОС в виде двунаправленного приоритетного списка, упорядоченного в соответствии с их номерами – идентификаторами процессов (PID).
Пример.
$ vi proc
date
ls
$sh proc
< дата>
f1
f2
$
Рассмотрим как реализуются процессы процедуры примера.
В ответ на приглашение -$ вводится имя процедуры proc и создается порожденный процесс shell. Он вводит данные, необходимые для своего выполнения из указанного файла proc - командные строки. Каждая команда sh-процедуры выполняется порожденным для неё процессом (как обычно для команды, введенной с клавиатуры - процессы утилит). Как только все команды окажутся выполненными, sh-процесс завершается и управление возвращается родительскому процессу. Процедура выполнена.
Планировщик обрабатывает процессы двух видов – обычные и более приоритетные процессы реального времени. Место в очереди определяется его приоритетом.
Процессы выполняются в одном из двух режимов- пользовательском и в режиме ядра. В режиме ядра выполняются процессы системных вызовов. В этом случае они имеют доступ к процедурам и структурам данных ядра. Такая организация позволяет ядру защитить свои процедуры и структуры системных данных от искажений со стороны проблемных задач.
|
Дескрипторы процессов создаются и удаляются динамически при выполнении процессов. Поэтому состав и размер списка постоянно меняются. Так как все процессы связаны между собой родственными отношениями, то списковая организация процессов используется для процессов одного ранга (например – для всех порожденных одним родительским или для всехродительских и т.п.). Таким образом вся система дескрипторов представляет собой некоторую древовидную структуру с коренным общисистемным процессом (swapper – имеющего идентификатор PID=0), который компилируется в состав ядра и используется для построения всей структуры дескрипторов и ее обработки. Открывается очередь наиболее приоритетным процессом инициатора ОС (init – PID=1), который строится первым при инициализпации ОС и уничтожается при завершении работы ОС.
Процессор выделяется каждому процессу в очереди на ограниченные кванты времени. Это принципиально отличает многозадачный режим обработки заданий в UNIX от однозадачного режима (DOS), где процессор выделяется процессам строго последовательно на все время выполнения процесса. В UNIX пересчет приоритетов происходит постоянно по прерываниям определенного типа с частотой - около одного раза в сек.
Часть инфориации дескриптора может быть выведена в листинг характеристик процесса с помощью специальной команды ps (см. ниже). Некоторые заголовки полей листинга:
- номер терминала, которому принадлежит процесс (TTY)
- приоритет (PRI)
- использованное время процессора (TIME)
- идентификатор процесса (PID)
- имя программы процесса или команды, выполняемой в теле процедуры на момент запроса листинга (CMD)
- идентификатор родительского процесса (PPID)
- адрес процесса (ADDR)
- величина изменения значения приоритета (NI) и пр..
Полную информацию о процессе пользователь или администратор может получить с помощью этой команды в следующем формате:
$ps [-k] [<входное_имя_пользователя>] - вывод листинга
характеристик процесса.
Некоторые значения ключей:
- -a[l] показать процессы данного терминала или
- -af полный (достаточный_ формат сообщения
- -afl длинный формат
- -u показать все активные процессы и пр..
Пример:
$ps -flu lev
PID PPID TTY PRI TIME CMD
927 1 tty5 0:04 sh
1001 927 tty5 0:02 ps
..
Для вывода листинга процессов, принадлежащих пользователю можно воспользоваться конструкцией:
$ps -f|grep <имя_пользователя>.
Тема 27. СОЗДАНИЕ ФОНОВЫХ ПРОЦЕССОВ
При обычном запуске с терминала некоторой программы на исполнение (системной утилиты или прикладной задачи) интерпретатором shell создается привилегированный процесс, который все время связан со своим терминалом. Запуск следующего процесса может быть выполнен пользователем только после завершения текущего, т.е. при появлении приглашения '$' от интерпретатора.
В целях использования возможности параллельного выполнения программ в ОС UNIX отдельные задачи или задания пакетного режима могут быть запущены одновременно с заданиями диалогового режима.Для запуска фонового (параллельного с другими потомками) процесса в командную строку необходимо и достаточно последним символом добавить знак
& (амперсанд):
$ cc prog.c &
$
Shell выводит номер этого процесса (PID) и разрешает ввод
следующей команды.
Фоновые процессы обладают некоторыми недостатками:
- не допускают ввода с клавиатуры;
-обеспечивают вывод на экран, но при этом нарушают целостность вывода диалогового процесса.
Общепринятый прием исключения влияния фонового вывода на интерактивную работу:
ком_строка>имя_файла.out &
- ком_строка планирует задание для фонового режима
- перенаправляет вывод вместо экрана в указанный файл головного каталога пользователя.
Пример:
$grep ааа* > grep.out &
$ps
PID TTY TIME CMD
194 tty5 0:02 grep
200 tty5 0:01 ps
Особенности работы с фоновым режимом:
- выполняемая в фоновым режиме программа (команда), требующая стандартного ввода, должна читать его из файла с использованием перенаправленного ввода;
- программа, выполняемая в фоновом режиме не может быть прервана <Ctrl*C>, т.к. она отсоединяется от клавиатуры и м.б. прекращена только с помощью команды kill или выходом из системы;
- выход из системы exit надо выполнять два раза: для завершения фонового процесса и завершения основного процесса shell.
В случаях, когда фоновый процесс все же требует ввода данных с клавиатуры, то его надо временно перевести в оперативный режим, ввести данные, и вернуть опять в фоновый с помощью следующих команд:
fg %N - перевод фонового процесса в оперативный;
bg %N - перевод оперативного в фоновый режим.
Здесь N – порядковый номер фонового задания, которое в общем случае может содержать несколько активных процессов и все они переводятся в соответствующий режим.
Номер задания “N” выводится:
- при запуске фоновой программы
- командой jobs без приостановленя или с приостановлением фонового процесса.
Приостановить выполнение процесса с выходом в shell (например для анализа состояния и результатов работы процедуры) можно с помощью прерывания-
<ctrl*Z>
$
с последующим запуском приостановленного процесса.
Пример.
$inf>f.out& - запуск процедуры inf в фоновом режиме
[1] 1754 - номер задания и идентификатор процесса
$jobs
%1 - номер задания
<ctrl*Z>
[1]+stopped inf>f.out
$bg %1 - запуск на продолжение в фоновом режиме
[1] inf>f.out
Выполнение фоновых заданий прекращается с выходом пользователя из системы. НО! Если фоновая программа должна быть продолжена и после прекращения текущего сеанса работы, то необходимо использовать команду:
$nohup имя_фоновой_программы & команда запускает и защищает фоновую программу от прерываний, вырабатываемых при выходе пользователя из системы, а также 2) перенаправляетфоновый протокол в системный файл nohup.out.
Вместе с тем, вывод протокола работы фоновой программы можно перенаправить в специальный файл, который просмотреть позже без нарушения протокола работы с оперативной задачей:
$nohup имя_фон_программы>имя_файла&
Рассмотрим два случая применения команды nohup.
Первый пример, где nohup перенаправляет протокол в указангный файл:
$nohup cat * > outfile &
[1] 972
$exit - завершается работа оперативного процесса
Повторный вход в систему:
login:
password:
$ps -af|grep cat - конвеер, выделяется строка с шаблоном cat
UID PID PPID CMD
lev 972 1 cat *>outfile &
$
В примере "процесс идет", nohup становится самостоятельным процессом и его PPID меняется - родительским процессом был sh (см. примеры выше), а стал init c PID=1, т.е. приоритет фонового процесса "усиливается" общесистемным процессом init и его выполнение будет продолжаться.
Примечание: в поле CMD может не указываться имя процедуры, а выводиться имя текущей утилиты этой процедуры, дентифицировать процедуру лучше по PID.
Если перенаправление протокола не использовать, то вывод автоматически осуществляется в систеный файл nohup.out, создаваемый системой в головном каталоге пользователя HOME.
Второй пример:
$nohup find / -user lev -type f &
[1] 2301
<сообщение о выводе в nohup.out>
$cd - переход в HOME
$cat nohup.out
<протокол команды find>
$
Команда nohup позволяет таким образом предупредить вывод на экран протокола фонового задания с прерыванием протокола работы оперативного процесса.
Пример: в чем разница в выполнении командных строк?
$PR;pr2;pr3 & - в фоновом режиме выполняется только pr3
$(PR1;pr2;pr3) & - в фоновом режиме выполняются все программы (подстановка опции & перед выполнением каждой программы из списка).
Тема 28. УПРАВЛЕНИЕ ПРИОРИТЕТАМИ
Максимальный приоритет процессов каждого пользователя группы устанавливает администратор. Если при выполнении задания образуются несколько порожденных процессов, то все они имеют одинаковый приоритет равный родительскому. В этом случае все процессы получают ресурсы равными долями (простой режим разделения времени). При необходимости выделения наиболее важных родительских процессов порожденным второстепенным можно понизить приоритет с помощью команды:
nice [-k] имя_программы выполнениепрограммы,указанной