|
| ||||||||||||
| ||||||||||||
Введение в POSIX'ивизм(C) Алексей Федорчук, 2005Опубликовано на сайте LinuxCenter Глава 7. Процесс пошел
Над нами солнце встает,
Процесс сам по себе идет... Тимур Шаов Содержание
Понятие процессаПонятие процесса принадлежит к тем сущностям, кажущимся интуитивно ясными, и которым, тем не менее, нелегко дать строгое (и при этом удобопонятное) определение. Наиболее распространенное их них - это представление процесса как программы в стадии ее выполнения (Андрей Робачевский. Операционная система Unix. СПб: БХВ-Петербург, 2000). Вместе с тем необходимо подчеркнуть, что процесс и программа - далеко не идентичные понятия. Во-первых, существуют процессы, которым не соответствует никакой программы (то есть никакого исполняемого файла). Во-вторых, программа в ходе своего выполнения может породить более одного процесса. В-третьих, в рамках одного процесса может происходить замещение одной программы другой. И наконец, в-четвертых - и это, пожалуй, главное, - при запуске программы порождение нового процесса предшествует собственно запуску программы. Все сказанное может показаться настолько кучерявым, что вызывает естественный вопрос: а за каким зеленым обычному (=конечному) пользователю-POSIX'ивисту вообще нужно знать о каких-то там процессах? Ведь пользователь MacOS (BSD-системы в своей основе - то есть тоже имеющей понятие процесса) спокойно обходится без этих знаний. Да и в Windows процессы, скорее всего, протекают, однако побуждений знакомиться с ними у пользователя нет ни малейшего. Причин к рассмотрению понятия процесса с позиций пользователя несколько. Первая, гносеологическая, - просто не кажется лишним знать, что там у этого пользователя в системе происходит (а, как уже говорилось, все, что происходит в системе - пользователя ли, админа, или программера - суть процессы). Однако есть и несколько моментов, более важных практически. Во-первых, понимание взаимоотношений между процессом и запущенной программой очень не вредно при всякого рода настроечных мероприятиях - дабы не удивляться, почему командная оболочка Разновидности процессовИтак, повторюсь: процесс - это все, что происходит в системе. А все происходящее в системе - либо порождено ее ядром (то есть как бы самой системой), либо - одним из ее пользователей. Соответственно этому, процессы бывают системные и пользовательские. На первых мы здесь задерживаться не будем. Скажу только, что запуск системных процессов осуществляется ядром ОС (не важно, какой - Linux там, или FreeBSD), и их задача - управление ресурсами машины (доступом к процессору, памяти, своппингом и т.д.). Важно только помнить, что с системными процессами не коррелируют никакие программы в обычном понимании этого слова (кроме ядра, конечно, которое само по себе - программа; но порождает она далеко не один процесс). То есть: в системе не существует отдельного исполняемого файла, ответственного за запуск программы, исполняемой системным процессом (внятно выразился?) - все они запускаются ядром, которое тоже являет собой просто исполняемый файл, хотя и не совсем обычный по своим функциям. Из сказанного выше существует единственное исключение, и это - процесс Процессы Процессы типа Есть еще и процессы интерактивные, отличающиеся тем, что привязаны к некоторому терминалу, через который пользователь может с ними взаимодействовать. Так, авторизовавшись в системе, пользователь (реальный - о виртуальных далее речи не будет) запускает тем самым свой первый процесс - свою "умолчальную" командную оболочку ( Атрибуты процессаКак же процесс соотносится с запустившим его пользователем? Для ответа нужно ознакомиться с атрибутами процесса. Сразу следует отметить, что любой процесс, системный ли, пользовательский, интерактивный или неинтерактивный, имеет следующие атрибуты:
Идентификатор процесса - это просто номер его в порядке запуска, от нуля до максимального значения, возможного в данной системе (количество одновременно запущенных процессов - величина конечная). Минимальный (нулевой) номер обычно получает процесс Идентификатор родительского процесса - это номер процесса, от которого произошел (посредством системного вызова Для рассмотрения смысла остальных атрибутов нам придется обратиться к команде Команда Итак, сразу после авторизации пользователя в ответ на команду USER PID COMMAND alv 5408 -zsh alv 5598 ps -u Первая колонка указывает на имя хозяина процесса - как правило (хотя и не обязательно - и позднее можно будет видеть, что это важно), таковым выступает пользователь, этот процесс запустивший. Вторая колонка - идентификатор процесса, третья - имя программы, породившей процесс; очевидно, что в момент сразу после авторизации это будет только командная оболочка - Сказанное относительно принадлежности процессов относится не только к интерактивным пользовательским процессам, но и к демонам. Хотя их, казалось бы, никто не запускает, но и они имеют своих хозяев. Это - те самые псевдопользователи, о которых я упоминал в предыдущей главе. Однако не обязательно хозяином процесса является запустивший его пользователь (или псевдопользователь). Это легко проверить, дав от лица обычного пользователя команду root 5617 passwd Как могло получиться, что обычный, непривилегированный, пользователь запустил процесс, хозяином которого оказался root? Это станет понятно из дальнейшего. Пока же скажу, для чего это нужно. Ясно, что любой пользователь должен иметь возможность сменить свой пароль. Однако для этого ему придется внести изменения в базу пользовательских акаунтов, а файл Более строго это можно описать так. Как было сказано, система работает не с именем пользователя (по большому счету оно ей до лампочки), а с его идентификатором (UID). Именно он обычно наследуется процессом в качестве идентификатора "хозяина" (и потому называется реальным UID). Однако у процесса есть еще и т.н. эффективный идентификатор "хозяина" (EUID), который собственно определяет привилегии данного процесса. Обычно UID и EUID совпадают - но бывают и исключения из этого правила. Если посмотреть их с помощью команды Кроме реального и эффективного идентификатора пользователя, для процесса устанавливаются еще два атрибута принадлежности - реальный и эффективный идентификаторы группы (GUID и EGUID, соответственно). Смысл их аналогичен, но они наследуют права доступа процесса для группы, к которой принадлежит запустивший процесс пользователь. Именно это дает возможность пользователю слушать музыку или выключать машину, о чем говорилось в предыдущей главе. Следующий атрибут процесса - его относительный приоритет (NICE), обозначаемый по английски словосочетанием nice value (что интерпретируется обычно как степень "дружелюбия" или "тактичности" по отношению к другим процессам). Он варьирует в диапазоне от -20 (минимальное "дружелюбие", то есть высший приоритет) до +20 (максимальное "дружелюбие", соответствующее низшему приоритету). Прикладные процессы в момент своего рождения получают приоритет 0 (то есть некую "среднюю" степень "дружелюбия"). Относительный приоритет процесса лишь косвенно связан собственно с приоритетами выполнения процессов, которые перераспределяются системой динамически, в зависимости от ряда факторов (и относительный приоритет - лишь один из них). Относительный приоритет сам по себе остается неизменным на протяжении всего времени существования процесса, хотя, как будет показано ниже, может быть изменен принудительно. Наконец, последний из упоминавшихся выше атрибутов процесса - терминал, с которым он связан. Атрибут этот имеет смысл только для прикладных процессов, запущенных пользователем с определенной консоли, реальной или виртуальной, от которой он и наследуется (хотя результаты выполнения процесса могут быть перенаправлены на другую консоль). Жизнь и смерть процессаКаждый пользовательский процесс порождается каким-либо другим процессом - в конечном счете, в первооснове их всех лежит процесс Каждый процесс в своем существовании проходит стадии зарождения, исполнения (часто с порождением новых процессов) и завершения (отмирания). Как все это выглядит в реальности, можно рассмотреть на примере самого первого пользовательского процесса, запускающего его командную оболочку по умолчанию (login shell). Для этого опять обратимся к выводу команды $ps l для того, чтобы видеть идентификаторы родительских процессов (за их показ отвечает опция $ ps l | grep v1 Для пустой, то есть не несущей пользовательского сеанса, консоли вывод последней команды будет примерно таким (я опускаю столбцы, содержание которых в данный момент для нас не существенно): UID PID PPID COMMAND 0 491 1 /usr/libexec/getty То есть мы имеем в этой консоли единственный процесс После же авторизации вывод той же команды приобретет такой вид: UID PID PPID COMMAND 0 491 1 login 1001 1949 491 -zsh Он свидетельствует, что в нашей экспериментальной консоли запущено уже два процесса - login, показывающий, что на ней зарегистрирован некий пользователь, и командная оболочка последнего - И еще прошу обратить внимание: PID процесса, ассоциированного с командой Вытеснение одной программы другой в рамках единого процесса - типичный способ запуска новой программы. Так, если из командной строки $ ps l | grep v1 увидим следующую картину: UID PID PPID COMMAND 0 491 1 login 1001 1949 491 -zsh 1001 2208 1949 joe которая может создать впечатление, будто бы процесс На самом деле родительский процесс перво-наперво порождает свою собственную копию - в данном случае еще один экземпляр командной оболочки В свою очередь, новый процесс также может выступать в качестве родительского. Так, редактор Как станет ясным из дальнейшего, понимание механизма создания процессов и запуска программ очень важно. В одной из следующих глав речь пойдет о командных оболочках и вызываемых из них командах. Так вот, большинство команд запускается именно таким образом, как описано выше. Что влечет за собой то, что запущенная программа наследует свойства (т.н. программное окружение) не той командной оболочки, которая выступает в качестве пользовательской, а от ее копии, которую команда заместила в рамках нового процесса. И вполне возможно, что программное окружение материнского и дочернего шеллов окажется разным, что не может не сказаться на выполнении команды. Управление процессамиЭто - одна из причин, почему я в своем пользовательском введении вообще заговорил о процессах. Вторая же причина - то, что необходимость управления процессами время от времени возникает перед пользователем с неотвратимостью рока. Управлять процессами можно двояко. Первый способ - это отдача прямой команды. Например, выход из редактора Очевидно, что прямое управление возможно только в отношении интерактивных пользовательских процессов, имеющих реально запустившего их хозяина, и управляющий терминал, с которого этот процесс запущен. С процессами-демонами же пользователь может взаимодействовать только посредством посылки им неких сигналов. Сигналы - это также единственный способ ликвидировать безнадежно зависший процесс, который невозможно остановить штатными средствами. Посылка сигналов осуществляется командой $ kill -15 ### где $ kill -TERM ### По получении сигнала Однако это ей не всегда удается - в этом случае процесс, соответствующий зависшей программе, продолжает существовать. И тут приходится прибегать к более жесткой форме: $ kill -9 ### или $ kill -KILL ### Сигнал Есть и еще один способ управления процессами - изменение их приоритета с целью перераспределения ресурсов машины. Однако на практике пользователю с этим почти не приходится сталкиваться, и потому эту тему я затрону лишь вкратце. Все пользовательские процессы (и большинство системных) по умолчанию запускаются с равным, как бы промежуточным, относительным приоритетом 0. И, соответственно, при многих запущенных задачах ресурсы компьютера (процессорное время и объем оперативной памяти) распределяются между ними (более или менее) равномерно. При необходимости перераспределения ресурсов между программами можно изменить приоритет выполнения какой-либо из них. При этом пользователь в состоянии только уменьшить приоритет одного или нескольких процессов, хозяином которых он является, администратор же имеет возможность и повысить приоритет любого процесса. Делается это двояко. Если требуется запустить программу с приоритетом, отличным от обычного, используется команда $ nice -5 joe запустит редактор $ nice --7 joe что приведет к росту приоритета (то есть уменьшению "дружелюбия") на семь единиц. Кроме того, приоритет может быть изменен для уже запущенных процессов с помощью команды $ renice 7 735 данная от лица пользователя - владельца процесса с PID 735, приведет к установке для него nice value, равного 7 (при условии, что прежний приоритет этого процесса был выше, например, 3 или 0). Администратор же может понизить приоритет того же процесса до значения nice value, равного 2, с помощью команды $ renice 2 735 или присвоить ему максимальный приоритет: $ renice -20 735 В завершение разговора о процессах повторю, что пользователь может управлять только теми процессами, хозяином которых он является - то есть собственноручно запущенными интерактивными. Администратор системы же располагает правами на управление всеми запущенными процессами, в том числе и неинтерактивными демонами. |
|
CITForum © 1997–2025