Европейский Университет в Санкт-Петербурге
Опубликован: 04.07.2008 | Доступ: свободный | Студентов: 1323 / 265 | Оценка: 4.34 / 3.65 | Длительность: 21:13:00
Лекция 9:

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

Взаимодействие процессов

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

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

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

Перенаправление потоков

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

find / -name "some_name" > names

Символ правой угловой скобки > означает перенаправление выходного потока запущенной программы в файл. При использовании этой конструкции файл names будет создан, а если он уже существует, то он будет уничтожен и будет создан новый файл с таким именем и новым содержимым.

Для добавления вывода программы в конец файла следует применять конструкцию "две правые угловые скобки" >>

find / -name "some_name" >> names

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

Можно перенаправить текст из файла во входной поток.

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

mail пользователь@компьютер < файл_с_письмом

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

Это дает возможность перенаправить ввод в процесс не из файла, а прямо из командной строки (или тела скрипта):

mail пользователь@компьютер <<FINAL
Дорогой(ая) $TARGETUSER,
Вы превысили допустимый размер домашнего каталога на $OVERSIZE
килобайт. Удалите ненужные Вам файлы, иначе это сделает робот!
Системный администратор
FINAL

Такой скрипт отправит по указанному адресу письмо, где вместо $TARGETUSER и $OVERSIZE будут подставлены имя того пользователя, которому предназначается письмо, и превышение лимита, соответственно. Естественно, этим переменным следует присвоить какое-то значение перед выполнением команды, но тот фрагмент скрипта, в котором это делается, вы с легкостью додумаете самостоятельно.

Указание в тексте значков << показывает что все, что следует непосредственно за ними до ближайшего символа-разделителя, является ограничителем текста. Символ-разделитель – это любой пустой символ: пробел, табуляция или конец строки. Все, что идет за ограничителем текста, передается во входной поток запущенного командой процеса вплоть до момента, когда в начале новой строки не встретится такой же ограничитель текста. Ограничитель может представлять собой любой набор непустых символов – неважно, просто ли это символ "точка", слово FINAL или что-то еще.

Кроме того, что потоки могут быть перенаправлены в файл или из файла, существует возможность перенаправить выходной поток одного процесса во входной поток другого. Направьте выходной поток программы ls во входной поток программы more, чтобы длинный список файлов вывести поэкранно:

ls –l | more

Символ вертикальной черты "|" означает перенаправление выходного потока программы, команда вызова которой находится слева от этого символа, во входной поток программы, вызываемой справа.

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

Например, для подсчета запущенных демонов httpd можно использовать такую конструкцию:

ps –auxw | grep httpd | wc –l

Программа ps выводит список всех процессов, запущенных в системе, grep выбирает из этого списка строки, в которых есть подстрока httpd, а wc с ключом l подсчитывает, как много строк оказалось в ее входном потоке.

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

Сигналы

Процессы могут взаимодействовать между собой, посылая друг другу сигналы. Список сигналов в Solaris ограничен сорока двумя сигналами, из которых наиболее употребительны TERM, KILL и HUP. В разных UNIX может быть разное количество сигналов, стандарт POSIX 1.1 определяет тридцать один сигнал. Каждый из них имеет свое мнемоническое обозначение и номер. В разных системах мнемонические обозначения остаются одинаковыми, а номер может быть разным.

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

С помощью команды

kill

можно послать сигнал с номером номер_сигнала процессу с идентификатором PID

kill –номер_сигнала PID

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

killall –номер_сигнала имя_процесса

В Solaris эта программа имеет другое значение, а именно выполняет отправку сигнала завершения всем активным процессам:

killall

А отправлять сигнал процессам с определенным именем в Solaris следует командой pkill.

pkill sendmail

С помощью pkill можно отправлять сигнал завершения TERM процессу с тем или иным признаком, отправка сигнала процессу с определенным именем – не единственное умение pkill. Например,

pkill –HUP –G other,daemon

отправит сигнал HUP (SIGHUP) всем процессам, чья фактическая группа – other или daemon.

В табл. 9.2 приведен список сигналов, определенный стандартом POSIX 1.1, а в табл. 9.3 – список сигналов, определенных в Solaris 9.

Таблица 9.2. Сигналы POSIX 1.1
Сигнал Номер Значение
SIGHUP 1 Разрыв связи с управляющим терминалом или управляющим процессом
SIGINT 2 Прерывание с клавиатуры
SIGQUIT 3 Сигнал выхода дан с клавиатуры
SIGILL 4 Недопустимая инструкция
SIGABRT 6 Сигнал abort получен от вызванной кем-то функции abort
SIGFPE 8 exception: ошибка вычислений с плавающей запятой
SIGKILL 9 Безусловное завершение процесса
SIGSEGV 11 Неверный адрес памяти
SIGPIPE 13 Запись в несуществующий канал
SIGALRM 14 Сигнал timer от функции alarm
SIGTERM 15 Завершение
SIGUSR1 30,10,16 Определяется пользователем
SIGUSR2 31,12,17 Определяется пользователем
SIGCHLD 20,17,18 Дочерний процесс остановлен или принудительно завершен
SIGCONT 19,18,25 Продолжить выполнение, если оно было остановлено
SIGSTOP 17,19,23 Остановить процесс
SIGTSTP 18,20,24 Остановить ввод с терминала
SIGTTIN 21,21,26 Ввод с терминала для фонового процесса
SIGTTOU 22,22,27 Вывод с терминала для фонового процесса

Кроме команды pkill системный администратор может найти удобной команду pgrep, которая заменяет конструкцию

ps –ef | grep команда

В Solaris для получения того же результата можно ввести более короткую команду

pgrep команда
Таблица 9.3. Сигналы Solaris 9
Название Знач. Действие по умолчанию Событие
SIGHUP 1 завершение разрыв связи с терминалом
SIGINT 2 завершение прерывание
SIGQUIT 3 аварийное завершение (core) Quit (see termio(7I))
SIGILL 4 аварийное завершение (core) недопустимая команда процессора
SIGTRAP 5 аварийное завершение (core) прерывание при трассировке или точке останова
SIGABRT 6 аварийное завершение (core) аварийное принудительное завершение
SIGEMT 7 аварийное завершение (core) прерывание эмуляции
SIGFPE 8 аварийное завершение (core) arithmetic exception: ошибка вычислений с плавающей запятой
SIGKILL 9 безусловное завершение требование безусловного завершения
SIGBUS 10 аварийное завершение (core) ошибка шины
SIGSEGV 11 аварийное завершение (core) ошибка сегментации (выход за пределы выделенной памяти)
SIGSYS 12 аварийное завершение (core) неверный системный вызов
SIGPIPE 13 завершение запись в несуществующий канал
SIGALRM 14 завершение сигнал timer от функции alarm
SIGTERM 15 завершение завершение
SIGUSR1 16 завершение программируемый сигнал 1
SIGUSR2 17 завершение программируемый сигнал 2
SIGCHLD 18 действия не выполняются изменение статуса дочернего процесса
SIGPWR 19 действия не выполняются сбой питания или перезагрузка
SIGWINCH 20 действия не выполняются изменение размера окна
SIGURG 21 действия не выполняются состояние сокета (Urgent Socket Condition)
SIGPOLL 22 завершение Pollable Event (see streamio(7I))
SIGSTOP 23 остановка требование остановки
SIGTSTP 24 остановка с терминала остановка ввода
SIGCONT 25 действия не выполняются требование продолжения
SIGTTIN 26 остановка ввода ввод с терминала для фонового процесса
SIGTTOU 27 остановка вывода вывод с терминала для фонового процесса
SIGVTALRM 28 завершение Virtual Timer Expired
SIGPROF 29 завершение Profiling Timer Expired
SIGXCPU 30 аварийное завершение (core) достижение лимита времени использования процессора (CPU time limit exceeded)
SIGXFSZ 31 аварийное завершение (core) превышение допустимого размера файла - getrlimit (see getrlimit(2))
SIGWAITING 32 действия не выполняются зарезервировано библиотекой потоков
SIGLWP 33 действия не выполняются межпроцессный (LWP) сигнал – зарезервировано библиотекой потоков
SIGFREEZE 34 действия не выполняются Check point Freeze
SIGTHAW 35 действия не выполняются Check point Thaw
SIGCANCEL 36 действия не выполняются Cancellation signal reserved by threads library
SIGXRES 37 действия не выполняются Resource control exceeded (see setrctl(2))
SIGRTMIN * завершение первый сигнал реального времени
(SIGRTMIN+1) * завершение второй сигнал реального времени
(SIGRTMAX-1) * завершение предпоследний сигнал реального времени
SIGRTMAX * завершение последний сигнал реального времени

Каналы и сокеты

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

Канал – это последовательность байт, используемая как однонаправленный поток ввода/вывода.

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

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

Для каждого процесса ядро хранит таблицу внутренних дескрипторов. По-английски эта таблица называется "descriptor table", и чтобы не путать ее с таблицей дескрипторов в файловой системе, мы называем внутреннюю таблицу дескрипторов, относящуюся к конкретному процессу, "таблицей внутренних дескрипторов". Слово "внутренних" подчеркивает то, что эти дескрипторы существуют только в пределах процесса, который пользуется ими для обращения к файлам. Эта таблица наследуется от родительского процесса, поэтому вместе с ней наследуется и доступ к объектам, на которые ссылаются дескрипторы (файлам, каналам, сокетам).

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

Подробнее о сокетах можно прочесть в socket (3).

Семафоры

Семафоры – это механизм, который принято использовать для контроля доступа нескольких процессов к одному ресурсу. Есть несколько реализаций программного интерфейса (API), связанного с семафорами:

  • вариант System V IPC (inter-process communication);
  • BSD;
  • POSIX 1003.1b.

Семафор по сути – это переменная, в зависимости от значения которой доступ к тому или иному ресурсу разрешается или блокируется до его освобождения. Семафоры широко используются в Oracle. Чтобы настроить подсистему семафоров в Solaris до версии 9 включительно (обеспечить достаточное количество семафоров в ядре), может потребоваться внести изменения в файл конфигурации ядра /etc/system. Для уточнения того, какие настройки требуются именно вашему программному обеспечению под Solaris, обратитесь к руководству по этому ПО.

Для Oracle8i в Oracle8i Installation Guide Release 3 рекомендуются следующие начальные значения параметров:

set semsys:seminfo_semmni=100
set semsys:seminfo_semmsl=<10+самое большое значение PROCESSES
                           среди ваших БД>
set semsys:seminfo_semmns=<столько, сколько объяснено ниже>
set semsys:seminfo_semopm=100
set semsys:seminfo_semvmx=32767

Значение seminfo_semmns рекомендуется установить равным сумме параметров PROCESSES всех баз данных сервера, причем самый большой из них должен быть просуммирован с коэффициентом 2, плюс еще 10 на каждую базу данных.

Посмотреть текущие значения параметров семафоров в Solaris до версии 9 включительно было можно по команде

sysdef | tail -25

Однако начиная с версии Solaris 10 для этого следует применять команду prctl, об использовании которой больше рассказывается в лекции 5 курса "Системное администрирование ОС Solaris 10".

Посмотреть текущие наборы семафоров в Solaris можно по команде

ipcs -sb

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

ipcrm -s semsetID

semsetID здесь означает идентификатор набора семафоров.

Александр Тагильцев
Александр Тагильцев

Где проводится профессиональная переподготовка "Системное администрирование Windows"? Что-то я не совсем понял как проводится обучение.