"Прикладные свободные программы и системы в школе" - читать интересную книгу автора (Отставнов Максим)1.6 ПроцессыНаряду с файлом, понятие Процесс — это обладающая уникальным идентификатором единица исполняемого кода[35] в памяти. Подавая простую команду из оболочки, оператор дает ОС указание запустить другой процесс. В ходе исполнения процесс может Подобно файлам, процессы в своем отношении друг к другу могут быть представлены в виде иерархии (дерева). В отличие от иерархии файлов, ребра этого дерева представляют не отношения вложенности, но отношения порождения («родитель-ребенок»). Процесс не может появиться в системе иначе, нежели будучи порожденным другим процессом, за очевидным исключением «корневого» процесса, запускаемого самим ядром при загрузке системы. Само ядро не является процессом[36]. Исследовать процессы можно стандартной командой «ps». Поданная без параметров, она выводит информацию о текущей оболочке и порожденных ею процессах. В выводе на Рис. 1-45 присутствуют четыре колонки. «PID» — это уникальный для системы В данном случае Алиса получила информацию о двух процессах: оболочке «bash» и внешней команде «ps»[37]. Команда «ps -A» выводит информацию обо всех процессах в системе[38]. В примере на Рис. 1-46 мы, подав команду из эмулятора терминала, для наглядности использовали ключ «-A» вместе с ключом «-l» («эль»), задающим «длинный» формат вывода (с дополнительными полями) и нестандартным ключом «-H», представляющим с помощью отступов в поле «CMD» отношения между процессами (вывод немного сокращен). Несколько иной набор параметров процесса можно получить, использовав вместо ключа «-l» ключ «-w», а ключ «-o» позволяет вывести для каждого процесса произвольный набор параметров из числа поддерживаемых системой, указав их мнемонику в качестве аргумента этого ключа. Стандартом определено пятнадцать параметров, к которым могут добавляться параметры, специфичные для конкретной системы. Мы разберем лишь некоторые из них. Обычно UID наследуется от процесса-родителя. Исключение составляют процессы-оболочки, запускаемые программой регистрации — их UID соответствует идентификатору зарегистрировавшегося пользователя, хотя UID самой программы регистрации — 0. Еще одно исключение — процессы, порожденные запуском программы из файла с установленным битом SUID. Их UID соответствует не породившему их процессу, а владельцу исполняемого файла. SUID (и подобный ему по эффекту бит GUID) — это мощный (и очень опасный) инструмент обхода системы распределения полномочий в ОС, поскольку позволяет пользователю запускать процессы с полномочиями выше собственных (в том числе, с полномочиями главного пользователя). Установить SUID бит может только главный пользователь. В аккуратно построенной и администрируемой системе количество программ с установленным SUID (и/или GUID) битом минимально. В нашем примере этот механизм с очевидностью использован при запуске процесса «X» (Икс-сервер — основной компонент графической системы, предоставляющий в распоряжение Икс-клиентов (программ с графическим интерфейсом) виртуальный X-терминал, связанный с физическими видеоадаптером, клавиатурой, мышью и системным динамиком), чьим родителем является процесс «xinit» с UID равным 504. Существенно, что Икс-клиенты (процессы «blackbox», «soffice.bin», «mozilla-bin», «xterm») выполняются с обычным пользовательским UID. Итак, в примере на Рис. 1-46 мы видим: находящийся в корне дерева процесс «init»; два порожденных им процесса, не имеющих управляющего терминала: демон управления системой энергосбережения «apmd»[40] и демон периодического исполнения заданий «crond»; порожденный процессом init процесс «login» с tty1 в качестве управляющего терминала; порожденный этим процессом «login» процесс «bash» — экземпляр оболочки также с tty1 в качестве управляющего терминала; порожденный процессом «bash» процесс «xinit» (это сценарий, запускающий компоненты графической среды); порожденные процессом «xinit» процессы «X» (это сервер оконной системы X, он запущен в качестве демона, т.е. без управляющего терминала) и «blackbox» (это менеджер окон графической среды); порожденные процессом «blackbox» процессы «soffice.bin» (это словарный процессор «OpenWriter», в котором набирается данный текст), «mozilla-bin» (браузер «Мозилла»), «xterm» (эмулятор текстового терминала). Они не имеют управляющего терминала; порожденный эмулятором терминала процесс оболочки «bash» с псевдотерминалом pts/0, назначенным при запуске эмулятора терминала, в качестве управляющего; порожденный этой оболочкой процесс «ps», который и осуществил приведенный в примере вывод; порожденный процессом «init» процесс «login» и порожденный им процесс «bash» на терминале tty2. Управление заданиями и сигнализация процессов В среде стандартной оболочки и команд открытой ОС запустить бесконечный процесс можно, введя команду «( while : ; do : ; done )», запускающую бесконечный цикл в подчиненном экземпляре оболочки (Рис. 1-47). Пока не нужно беспокоиться о понятности синтаксиса управляющих конструкций. Если Алиса все сделала правильно, то сценарий сам по себе уже не остановится никогда (скорее всего, до разгрузки системы). Приглашения оболочки Алиса тоже уже не получит, поэтому даже не сможет выйти из системы. Справиться с этой ситуацией ей поможет клавиатурная комбинация Control-C. Как и комбинация Control-D, она не отображается на экране, но после ее нажатия Алиса получает приглашение оболочки и при помощи команды «ps» убеждается, что никаких процессов, кроме самой оболочки и «ps», под этой оболочкой не выполняется. Клавиатурная комбинация Control-C побуждает драйвер терминала отправить сигнал нормального завершения выполняемому процессу (в данном случае, подчиненной оболочке). Клавиатурная комбинация Control-Z побуждает драйвер терминала отправить выполняемому процессу другой сигнал — приостановки[41]. После нажатия Control-Z оболочка выдает сообщение, состоящее из числа в квадратных скобках, слова «остановлен» («stopped» в стандартной локали) и введенной ранее команды (Рис. 1-49). Число в квадратных скобках — это номер Состояние соответствующего процесса (колонка «S» в выводе «ps -l» (эль)) обозначено буквой «T», означающей, что процесс В любой момент времени на переднем плане каждого управляющего терминала находится не более одного задания. Заданий заднего плана может быть неограниченное[43] количество. В примере на Рис. 1-50 Алиса запускает сценарий «цикл», останавливает его нажатием Control-Z, затем возобновляет его выполнение на переднем плане командой «fg», снова останавливает, и затем возобновляет на заднем плане командой «bg». После этого Алиса сразу получает приглашение и, введя команду «ps -l», видит соответствующий выполнению сценария процесс «bash» (PID 2765) с состоянием «R» («выполняемый»). Нажатие клавиатурных комбинаций Control-C и Control-Z всегда вызывает передачу сигнала заданию переднего плана. Заданию заднего плана передавать сигнал можно только явно, для чего служит команда «kill». Указание в качестве ее единственного аргумента идентификатора процесса приводит к тому, что процессу передается сигнал «нормально завершиться» (это соответствует нажатию комбинации Control-C для задания переднего плана) (Рис. 1-51). Подача команды «kill» с ключом «-s» и Реализация может предусматривать большее их количество[44]. Практически во всех системах реализован сигнал SIGSTOP, его отправка процессу переднего плана большинством современных оболочек осуществляется нажатием Control-Z, как описано выше. На пользовательском уровне применяются обычно сигналы SIGTERM и SIGKILL. Отличие их в том, что при получении первого из них процесс по возможности завершается «чисто»: сбрасывает содержимое внутренних буферов в файлы и закрывает их, а второго — завершается немедленно. Второй используется обычно для «убиения» процесса, выполняющего ошибочную программу. До сих пор Алиса отправляла сигналы по собственной инициативе. Отправляющим процессом выступали оболочка (при передаче сигналов процессу переднего плана нажатием клавиш) или команда «kill». Но передача сигналов (межпроцессная коммуникация) может осуществляться между любыми процессами, и является широко используемым в системном и прикладном программировании механизмом ОС. Как и при доступе к файлам, при доступе к процессам ОС руководствуется системой распределения полномочий. Стандартное поведение проще, чем в случае с файлами: процесс, запущенный обычным пользователем (не главным пользователем), может сигнализировать процессу, запущенному тем же пользователем, и не может сигнализировать процессу, которым «владеет» другой пользователь. В примере на Рис. 1-53 попытка Алисы «убить» процесс, принадлежащий другому пользователю, привела к сообщению об ошибке. Реализацией может быть определено более сложное поведение[45]. Программа может переопределить смысл сигналов, которые получает процесс (в частности, отменить завершение процесса), за исключением сигнала SIGKILL. Все стандартные команды ОС обрабатывают сигналы стандартным образом[46]. Если вам не удается завершить запущенный вами процесс подачей команды «kill -s SIGKILL», значит, в системе возникли Вы также можете столкнуться с ситуацией, когда программа переопределяет SIGINT, SIGSTOP и входит в бесконечный цикл (или ожидает события, наступления которого в обозримом будущем не предвидится). Запустив такую программу на переднем плане, вы не сможете завершить ее нажатием Control-C или приостановить нажатием Control-Z, а подать SIGKILL командой «kill» также будет невозможно, поскольку оболочка ожидает завершения процесса переднего плана. Простого выхода из этой ситуации нет, но обычно можно зарегистрироваться на другом терминале (включая виртуальную консоль) и «убить» хитрый процесс командой «kill -s SIGKILL». Если таким образом «завис» сеанс в окне виртуального терминала, его обычно можно «убить» средствами оконного менеджера (закрыв окно). Наконец, если вы работаете на последовательном терминале, можно попытаться выключить и снова включить его. Оболочка по выключении получит сигнал SIGHUP и «убьет» подчиненные себе процессы. Сложные команды и задания Чтобы запустить задание на заднем плане, не обязательно запускать его на переднем плане, приостанавливать и возобновлять командой «bg». Можно воспользоваться Использование символа завершения «amp;» позволяет ввести в одной строке более одной команды (и, соответственно, запустить более одного задания), связав их этим символом (Рис. 1-55). Список заданий можно получить командой «jobs». Знак «+» после номера задания обозначает «текущее» задание, то есть задание, которым можно управлять командами «bg» и «fg» без аргументов. Знаком «-» помечено «предыдущее» задание (которое станет текущим по завершению текущего). При переводе задания переднего плана на задний или запуске нового задания текущее задание (если оно есть) становится «предыдущим», а вновь запущенное — текущим. Если нужно возобновить исполнение задания на переднем или заднем плане, или перевести задание на передний план, можно воспользоваться командами «fg» и «bg», задав им аргумент, состоящий из «%» («процент»), и следующим за ним слитно номером задания (Рис. 1-56). Другим символом завершения команды, также позволяющим подать более одной команды и инициировать более одного задания одной строкой является «;» (точка с запятой). Команда, завершенная этим символом, будет выполняться на переднем плане, а последующие команды (задания) будут выполняться после ее завершения. При подаче сложных команд (команд, включающих в себя более одной команды) их можно группировать с использованием круглых скобок. Сгруппированные скобками команды (вне зависимости от использованного символа завершения) образуют Кроме того, группировка бывает полезна, чтобы передать значение переменной сразу всем командам, или перенаправить ввод и/или вывод всех команд. Механизм управления заданиями (являющийся позднейшей добавкой к концепции открытых систем) чрезвычайно полезен при выполнении сложных работ с алфавитно-цифрового терминала. Сегодня операторы предпочитают при возможности запускать разные программы в разных окнах виртуальных терминалов в графической среде. Тем не менее, полезно хотя бы в общих чертах представлять, что это такое. Существуют также символы завершения команды «amp;amp;» и «||». Их действие связано с понятием |
||||||||||||||||||||||||||||||
|