Процессы
"Процесс - одно из фундаментальнейших понятий операционной системы Unix, наряду с другой такой же фундаментальной абстракцией - понятием файла."
Robert Love "Linux Kernel Development" Роберт Love_Системное программирование
Процессы в операционной системе UNIX играют ключевую роль. От оптимальной настройки подсистемы управления процессами и числа одновременно выполняющихся процессов зависит загрузка ресурсов процессора, что в свою очередь имеет непосредственное влияние на производительность системы в целом. Ядро операционной системы предоставляет задачам базовый набор услуг, определяемый интерфейсом системных вызовов. К ним относятся основные операции по работе с файлами, управление процессами и памятью, поддержка межпроцессного взаимодействия. Дополнительные функциональные возможности системы, т. е. услуги, которые она предоставляет пользователям, определяются активными процессами. От того, какие процессы выполняются в вашей системе, зависит, является ли она сервером базы данных или сервером сетевого доступа, средством проектирования или вычислительным сервером. Даже так называемые уровни выполнения системы (runlevels ...и здесь), представляют собой удобный способ определения группы выполняющихся процессов и, соответственно, функциональности системы.
В.А.Костромин <<---PDF А.Робачевский <<---PDF Роберт Лав <<---PDF W.Stevens Взаимодействие процессов <<--PDF Таненбаум <<---PDFUNIX Лекция 1 UNIX Лекция 2 UNIX Лекция 3 UNIX Лекция 4 UNIX Лекция 5
Модель процесса
В многозадачной системе процессор переключается между программами, предоставляя каждой от десятков до сотен миллисекунд. При этом в каждый конкретный момент времени процессор занят только одной программой, но за секунду он успевает поработать с несколькими программами, создавая у пользователей иллюзию параллельной работы со всеми программами. Иногда в этом контексте говорят о псевдопараллелизме, в отличие от настоящего параллелизма в многопроцессорных системах (в которых установлено два и более процессора, разделяющих между собой общую физическую память). Следить за работой параллельно идущих процессов достаточно трудно, поэтому со временем разработчики операционных систем разработали концептуальную модель последовательных процессов, упрощающую эту работу. В этой модели все функционирующее на компьютере программное обеспечение, иногда включая собственно операционную систему, организовано в виде набора последовательных процессов, или, для краткости, просто процессов.
Процессом является выполняемая программа, включая текущие значения счетчика команд, регистров и переменных.
Процесс основная еденица работы для операционной системы в машинах третьего поколения. С позиций данной абстрактной модели, у каждого процесса есть собственный виртуальный центральный процессор. На самом деле, разумеется, реальный процессор переключается с процесса на процесс, но для лучшего понимания системы значительно проще рассматривать набор процессов, идущих параллельно (псевдопараллельно), чем пытаться представить себе процессор, переключающийся от программы к программе, это переключение и называется многозадачностью или мультипрограммированием.
В условиях многозадачности каждый процесс имеет свою управляющую логику (то есть логический счетчик команд) идущую (идущие) не зависимо друг от друга. Разумеется, на самом деле существует только один физический счетчик команд, в который загружается логический счетчик команд текущего процесса. Когда время, отведенное текущему процессу, заканчивается, физический счетчик команд сохраняется в логическом счетчике команд процесса в памяти.
Программы и процессы
Обычно программой называют совокупность файлов, будь то набор исходных текстов, объектных файлов или собственно выполняемый файл. Для того чтобы программа могла быть запущена на выполнение, операционная система сначала должна создать окружение или среду выполнения задачи, куда относятся ресурсы памяти, возможность доступа к устройствам ввода/вывода и различным системным ресурсам, включая услуги ядра. Это окружение (среда выполнения задачи) получило название процесса. Мы можем представить процесс как совокупность данных ядра системы, необходимых для описания образа программы в памяти и управления ее выполнением. Мы можем также представить процесс как программу в стадии ее выполнения, поскольку все выполняющиеся программы представлены в UNIX в виде процессов. Процесс состоит из инструкций (~команд), выполняемых процессором (совокупность отдельных операций процессора, определенных единой системой команд), данных и информации о выполняемой задаче, такой как размещенная память, открытые файлы и статус процесса.
С каждым процессом связывается его адресное пространство — список адресов в памяти от некоторого минимума (обычно нуля) до некоторого максимума, которые процесс может прочесть и в которые он может писать. Адресное пространство содержит саму программу, данные к ней и ее стек. Со всяким процессом связывается некий набор регистров, то есть памяти внутри процессора, соответственно памяти "сверхбыстрой" включая счетчик команд, указатель стека и другие аппаратные регистры, плюс вся остальная информация, необходимая для запуска программы.
В то же время не следует отождествлять процесс с программой хотя бы потому, что программа может породить более одного процесса. (Программа — согласно ГОСТ 1978190 — данные, предназначенные для управления конкретными компонентами системы обработки информации в целях реализации определённого алгоритма.) Простейшие программы, например, whoили cat, при выполнении представлены только одним процессом. Сложные задачи, например системные серверы (печати, FTP, Telnet), порождают в системе несколько одновременно выполняющихся процессов. Операционная система UNIX является многозадачной. Это значит, что одновременно может выполняться несколько процессов, причем часть процессов могут являться образцами одной программы. Различие между процессом и программой трудноуловимо и тем не менее имеет принципиальное значение.
Выполнение процесса заключается в точном следовании набору инструкций, который никогда не передает управление набору инструкций другого процесса. Процесс считывает и записывает информацию в раздел данных и в стек, но ему недоступны данные и стеки других процессов. В то же время процессы имеют возможность обмениваться друг с другом данными с помощью предоставляемой UNIX системой межпроцессного взаимодействия. В UNIX существует набор средств взаимодействия между процессами, таких как:
сигналы (signals), (UNIX Лекция 6)
каналы (pipes), (UNIX Лекция 5)
разделяемая память (shared memory)
семафоры (semaphores), (UNIX Лекция 7) (http://cs.mipt.ru)
сообщения (messages) и файлы ......но в остальном процессы изолированы друг от друга.
Типы процессов
Системные процессы
Системные процессы являются частью ядра и всегда расположены в оперативной памяти. Системные процессы не имеют соответствующих им программ в виде исполняемых файлов и запускаются особым образом при инициализации ядра системы. Выполняемые инструкции и данные этих процессов находятся в ядре системы, таким образом они могут вызывать функции и обращаться к данным, недоступным для остальных процессов. Системными процессами являются:
shed (диспетчер свопинга),
vhand (диспетчер страничного замещения),
bdfflush (диспетчер буферного кэша)
kmadaemon (диспетчер памяти ядра).
К системным процессам следует отнести init, являющийся прародителем всех остальных процессов в UNIX. Хотя init не является частью ядра, и его запуск происходит из исполняемого файла (/etc/init), его работа жизненно важна для функционирования всей системы в целом.
Демоны
Демоны (www.freedesktop.org) — это неинтерактивные процессы, которые запускаются обычным образом — путем загрузки в память соответствующих им программ (исполняемых файлов), и выполняются в фоновом режиме. Обычно демоны запускаются при инициализации системы (но после инициализации ядра) и обеспечивают работу различных подсистем UNIX: системы терминального доступа, системы печати, системы сетевого доступа и сетевых услуг и т. п. Демоны не связаны ни с одним пользовательским сеансом работы и не могут непосредственно управляться пользователем. Большую часть времени демоны ожидают пока тот или иной процесс запросит определенную услугу, например, доступ к файловому архиву или печать документа.Отдельной темой является Systemd (как и безвременно нас покинувший Upstart)— демон инициализации других демонов в Linux, который используется вместо SystemV Init (sysvinit). Критики считают, что демон systemd берёт на себя неоправданно много функций и превращается в главную угрозу стабильности системы.
Прикладные процессы
К прикладным процессам относятся все остальные процессы, выполняющиеся в системе. Как правило, это процессы, порожденные в рамках пользовательского сеанса работы. С такими процессами мы сталкиваемся чаще всего. Например, запуск команды lsпородит соответствующий процесс этого типа. Важнейшим пользовательским процессом является основной командный интерпретатор login shell, который обеспечивает нашу работу в UNIX. Он запускается сразу же после регистрации в системе, а завершение работы login shell приводит к отключению от системы. Инициатором login является программа getty (сокращение от get teletype).Программа выводит приглашение и ожидает активности пользователя, который может захотеть работать именно на этом терминале. Введённое входное имя getty передаёт программе login, которая вводит пароль и определяет, разрешено ли работать в системе с этим входным именем и этим паролем. Если login приходит к выводу, что работать можно, он запускает стартовый командный интерпретатор, посредством которого пользователь и командует системой.
Пользовательские процессы могут выполняться как в интерактивном, так и в фоновом режиме, но в любом случае время их жизни (и выполнения) ограничено сеансом работы пользователя. При выходе из системы все пользовательские процессы будут уничтожены.
Интерактивные процессы монопольно владеют терминалом, и пока такой процесс не завершит свое выполнение, пользователь не сможет работать с другими приложениями. Вы сможете работать с другими приложениями, если в функции интерактивного процесса входит запуск на выполнение других программ. Примером такой задачи является командный интерпретатор shell, который считывает пользовательский ввод и запускает соответствующие задачи. Более типичным в данном контексте является процесс, порожденный командой ps. Пока ps не завершит работу, вы не сможете вводить команды shell.
Атрибуты процесса
Процесс в UNIX имеет несколько атрибутов, позволяющих операционной системе эффективно управлять его работой, важнейшие из которых рассмотрены ниже.
Идентификатор процесса Process ID (PID)
Каждый процесс имеет уникальный идентификатор PID, позволяющий ядру системы различать процессы. Когда создается новый процесс, ядро присваивает ему следующий свободный (т. е. не ассоциированный ни с каким процессом) идентификатор. Присвоение идентификаторов происходит по возрастающий, т. е. идентификатор нового процесса больше, чем идентификатор процесса, созданного перед ним. Если идентификатор достиг максимального значения, следующий процесс получит минимальный свободный PID и цикл повторяется. Когда процесс завершает свою работу, ядро освобождает занятый им идентификатор.
Идентификатор родительского процесса Parent Process ID (PPID)
Идентификатор процесса, породившего данный процесс.
Приоритет процесса (Nice Number)
Относительный приоритет процесса, учитываемый планировщиком при определении очередности запуска. Фактическое же распределение процессорных ресурсов определяется приоритетом выполнения, зависящим от нескольких факторов, в частности от заданного относительного приоритета. Относительный приоритет не изменяется системой на всем протяжении жизни процесса (хотя может быть изменен пользователем или администратором) в отличие от приоритета выполнения, динамически обновляемого ядром.
Терминальная линия (TTY)
Терминал или псевдотерминал, ассоциированный с процессом, если такой существует. Процессы-демоны не имеют ассоциированного терминала.
Реальный (RID) и эффективный (EUID) идентификаторы пользователя
RID Реальным идентификатором пользователя данного процесса является идентификатор пользователя, запустившего процесс.
EUID Эффективный идентификатор служит для определения прав доступа процесса к системным ресурсам (в первую очередь к ресурсам файловой системы).
Обычно реальный и эффективный идентификаторы эквивалентны, т. е. процесс имеет в системе те же права, что и пользователь, запустивший его. Однако существует возможность задать процессу более широкие права, чем права пользователя путем установки флага SUID, когда эффективному идентификатору присваивается значение идентификатора владельца исполняемого файла (например, администратора).
Реальный (RGID) и эффективный (EGID) идентификаторы группы
RGID Реальный идентификатор группы равен идентификатору первичной или текущей группы пользователя, запустившего процесс.
EGID Эффективный идентификатор служит для определения прав доступа к системным ресурсам по классу доступа группы.
Так же как и для эффективного идентификатора пользователя, возможна его установка равным идентификатору группы владельца исполняемого файла (флаг SGID).
Команда ps (process status) позволяет вывести список процессов выполняющихся в системе, и их атрибуты, как и top, atop и более удобная утилита htop:
Жизненный путь процесса
Процесс в UNIX создается системным вызовом fork. Процесс, сделавший вызов fork называется родительским, а вновь созданный процесс — дочерним. Новый процесс является точной копией породившего его процесса. Как это ни удивительно, но новый процесс имеет те же инструкции и данные, что и его родитель. Более того, выполнение родительского и дочернего процесса начнется с одной и той же инструкции, следующей за вызовом fork. Единственно, чем они различаются — это идентификатором процесса PID (не совсем это так --->>[3]) . Каждый процесс имеет одного родителя, но может иметь несколько дочерних процессов.
Для запуска задачи, т. е. для загрузки новой программы, для того что бы это не был просто чистый клон родителя (после fork), процесс должен выполнить системный вызов ехес. При этом новый процесс не порождается, а исполняемый код процесса полностью замещается кодом запускаемой программы. Тем не менее окружение новой программы во многом сохраняется, в частности сохраняются значения переменных окружения, назначения стандартных потоков ввода/вывода, вывода сообщений об ошибках, а также приоритет процесса.
В UNIX запуск на выполнение новой программы часто связан с порождением нового процесса, таким образом сначала процесс выполняет вызов fork, порождая дочерний процесс, который затем выполняет ехес, полностью замещаясь новой программой. Важно понимать разницу между системными вызовами fork и exec Системный вызов fork создает новый процесс, у которого пользовательский контекст совпадает с пользовательским контекстом процесса-родителя.
Системный вызов exec изменяет пользовательский контекст текущего процесса, не создавая новый процесс, можно понимать это как наложение образа программы на выполняемый процесс.
Рассмотрим пример.
Допустим, пользователь, работая в командном режиме (в командном интерпретаторе shell) запускает команду ls.Текущий процесс (shell) делает вызов fork, порождая вторую копию shell. В свою очередь, порожденный shell вызывает ехес, указывая в качестве параметра имя исполняемого файла, образ которого необходимо загрузить в память вместо кода shell. Код ls замещает код порожденного shell, и утилита ls начинает выполняться. По завершении работы ls созданный процесс "умирает". Пользователь вновь возвращается в командный режим.
Описанная процедура запуска новой программы называется fork-and-exec.
Однако бывают ситуации, когда достаточно одного вызова fork без последующего ехес. В этом случае исполняемый код родительского процесса должен содержать логическое ветвление для родительского и дочернего процессов.
Все процессы в UNIX создаются посредством вызова fork. Запуск на выполнение новых задач осуществляется либо по схеме fork-and-exec, либо с помощью ехес. "Прародителем" всех процессов является процесс init, называемый также распределителем процессов, init (процесс с номером 1) живет "вечно" хоронит детей и усыновляет их потомков, ибо! каждый процесс должен иметь родителей, каждый но не init. Если построить граф "родственных отношений" между процессами, то получится дерево, корнем которого является init. Показанные (на рис. ниже) процессы sched и vhand (процесс замещения страниц, который затем становится процессом подкачки) являются системными и формально не входят в иерархию.
Стандартным пример для понимания утилиты exec это сделать перенаправление вывода оболочки:
$ exec > file_examlpe
после чего вывод терминала будет перенаправляться в файл file_examlpe о чем нам явно сообщит утилита cat:
$ cat file_examlpe
cat: file_examlpe: input file is output file
$
https://sites.google.com/site/bashhackers/commands/exec
http://espressocode.top/exec-command-examples/
Если сделать "отпечаток" выполняемых процессов, например командой ps, между указанными стадиями, результат был бы следующим: Пользователь работает в командном режиме:
UID PID PPID С STIME TTY TIME CMD
user 745 1 10 10:11:34 ttyp4 0:01 sh
Пользователь запустил команду ls, и shell произвел вызов fork
UID PID PPID С STIME TTY TIME CMD
user 745 1 10 10:11:34 ttyp4 0:01 sh
user 802 745 14 11:00:00 ttyp4 0:00 sh
После создания процессов ядра ядро создает первый процесс для выполнения программы в режиме пользователя; он служит в качестве родительского процесса для всех последующих процессов. Первым процессом режима пользователя является init, исторически - процесс 1. Этот процесс выполняет административные задачи, такие, как порождение процессов getty для каждого терминала на машине, сбор состояния завершения покинутых процессов и обработка упорядоченного перевода системы из многопользовательского в однопользовательский режим. Процесс init является процессом режима пользователя, работающим вне ядра
After initializing its tables, the kernel creates three dummy processes; sched, vhand and bdflush (with process IDs 0, 2 and 3 respectively). These processes are sections of kernel code which must be called periodically; vhand provides virtual memory paging services, sched provides swapping services, and bdflushflushes the buffer cache periodically. None of these processes can be killed; they are part of the kernel, and are essential to the correct running of the UNIX system.(здесь)
Выше представлен "стандартный" процесс загрузки операционных систем семейства *nix. После загрузки ядра системы выполняется переход в интерактивный режим , представленный либо графическим интерфейсом либо интерфейсом командной строки.
Положим, что первым запускаемым в ходе загрузки процессом, является программа инициализации init, которая считывает содержимое конфигурационного файла /etc/inittab, определяет перечень и характеристики терминалов, имеющихся в системе, и вызывает программу интерактивного входа getty(get tty), отображающую приглашение для ввода имени пользователя (ну и конечно initd, как же без демонов). После ввода имени пользователя и пароля, программа getty вызывает программу login, которая проверяет достоверность учетной записи, выполняет переход в домашний каталог пользователя и передает управление интерпретатору команд, в качестве которой используется программа оболочки пользователя, конкретная разновидность которой определяется содержимым файла /etc/passwd для данной учетной записи и прописана явным образом в последнеи позиции файла : root:x:0:0:Super-User:/root:/usr/bin/sh .
sh по факту не совсем оболочка, или не только оболочка, скорее это спецификация стандарта операционной системы POSIX для работы оболочки. Сценарии, предназначенный для этой спецификации, может быть выполнен любой совместимой с POSIX оболочкой, такой как: bash, ksh, csh, ash, zsh, tcsh.
Функции выполняемые оболочками, а точнее интерпретаторами команд стандартны и определены спецификой работы в терминале:
Интерпретация командной строки.
Доступ к командам и результатам их выполнения.
Поддержка переменных , специальных символов и зарезервированных слов.
Обработка файлов, операций стандартного ввода и вывода.
Реализация специального языка программирования оболочки.
Сигналы
Сигналы (UNIX Лекция 6) являются способом передачи от одного процесса другому или от ядра операционной системы какому-либо процессу уведомления о возникновении определенного события. Сигналы можно рассматривать как простейшую форму межпроцессного взаимодействия. В то же время сигналы больше напоминают программные прерывания, — средство, с помощью которого нормальное выполнение процесса может быть прервано. Например, если процесс производит деление на Ø, ядро посылает ему сигнал SIGFPE, а при нажатии клавиш прерывания, обычно Del или Ctrl+C, текущему процессу посылается сигнал SIGINT (interrupt — прервать), и как выясняется «^C» — это не волшебная кнопка-убийца, а предварительно установленный символ (с ascii-кодом 3). Такое ветвление можно организовать на основании значения, возвращаемого системным вызовом fork. Для родительского процесса fork возвращает идентификатор созданного дочернего процесса, а дочерний процесс получает значение, равное Ø.
Для отправления сигнала служит команда kill: kill [sig_no] [pid] где:
sig_nо — номер или символическое название сигнала
pid — идентификатор процесса, которому посылается сигнал.
Администратор системы может посылать сигналы любым процессам, обычный же пользователь может посылать сигналы только процессам, владельцем которых он является (реальный и эффективный идентификаторы процесса должны совпадать с идентификатором пользователя). Например, чтобы послать процессу, который вы только что запустили в фоновом режиме, сигнал завершения выполнения SIGTERM, можно воспользоваться командой:
$ my_program & #Запустим программу в фоновом режиме
$ kill $! #По умолчанию команда kill посылает сигнал SIGTERM;
#переменная $! содержит PID последнего процесса, запущенного в
#фоновом режиме
При получении сигнала процесс имеет три варианта действий для выбора:
1. Он может игнорировать сигнал. Не следует игнорировать сигналы, вызванные аппаратной частью, например, при делении на Ø или ссылке на недопустимые области памяти, так как дальнейшие результаты в отношении данного процесса непредсказуемы.
2. Процесс может потребовать действия по умолчанию. Как ни печально, обычно это сводится к завершению выполнения процесса.
3. Наконец, процесс может перехватить сигнал и самостоятельно обработать его. Например, перехват сигнала SIGINT позволит процессу удалить созданные им временные файлы, короче, достойно подготовиться к "смерти". Следует иметь в виду, что сигналы SIGKILL и SIGSTOP нельзя ни перехватить, ни игнорировать.
По умолчанию команда kill посылает сигнал с номером -15 — sigterm, действие по умолчанию для которого — завершение выполнения процесса, получившего сигнал.Иногда процесс продолжает существовать и после отправления сигнала SIGTERM. В этом случае можно применить более жесткое средство — послать процессу сигнал SIGKILL с номером -9, — поскольку этот сигнал нельзя ни перехватить, ни игнорировать: $ kill -9 pid
Однако возможны ситуации, когда процесс не исчезает и в этом случае. Это может произойти для следующих процессов:
Процессы-зомби. Фактически процесса как такового не существует, осталась лишь запись в системной таблице процессов, удалить его можно только завершив родительский процесс. Состояние "зомби" есть естественный этап жизни процесса, в финансах это называется "волатильность" (показатель в смысле изменчивости и меры рисков, количество зомби и будет волатильность используемого программного обеспечения) найти зомби-процессы можно выполнив:
$ ps aux | grep defunct или $ ps -ef | grep defunct
defunct(de function) название говорит само за себя, это и есть "зомби-процессы" в выводе grep, и поскольку ни какой kill -9 не даст желаемого результата, надо найти и замочить родителя, как ..?, просто: $ ps -xal | grep defunct. Зомби в небольших количествах не представляют опасности, однако если их много, это может привести к переполнению таблицы процессов, но это уже вопрос качества програмного обеспечения, как с этим бороться ?.., ответ очевиден, вообщем не надо ставит перед собой героических задачь перестрелять всех зомби, помня что убив родителя мы убиваем сервис им порожденный, до поры до времени они "хорошие", но всему в этом мире положена "мера".
PS: И все же, если у вас плохое настроение попробуйте ЭТО:
$ ps axo state,ppid | awk '!/PPID/$1~"Z"{print $2}' | xargs -r kill -9
ЭТО попробует убить их всех (если получится)
Процессы, ожидающие недоступные ресурсы NFS (Network File System), например, записывающие данные в файл файловой системы удаленного компьютера, отключившегося от сети. Эту ситуацию можно преодолеть, послав процессу сигнал SIGINT или SIGQUIT.
Процессы, ожидающие завершения операции с устройством, например, перемотки магнитной ленты.
Как правило это преждевременная смерть родителя и в результате не сумел принять код завершения.
Сигналы могут не только использоваться для завершения выполнения процессов, но и иметь специфическое для приложения (обычно для системных демонов) значение (естественно, это не относится к сигналам SIGKILL и SIGSTOP). Например, отправление сигнала SIGHUP (HangUP) серверу имен DNS (named) вызовет считывание базы данных с диска. Для других приложений могут быть определены другие сигналы и соответствующие им значения.
Соответствие между символьными именами и номерами сигналов может отличаться в различных версиях UNIX.
Команда kill -l выводит номера сигналов и их имена...............читать ЭТО!, и это здорово , еще лучше прочесть:
Морис Дж. Бах - "Архитектура операционной системы UNIX" ТУТ
Забродин Л.Д Операционная система UNIX ст. 64-76 <<---PDF
ПРОЦЕССЫ В UNIX
УПРАВЛЕНИЕ ПРОЦЕССАМИ
UNIX — многопользовательская многозадачная операционная система. Концепция процесса является базовой для архитектуры ОС. Процесс строится для каждой прикладной (например, sh- процедуры) и системной задачи (например, утилиты) с помощью системного вызова fork. Является единицей вычислительной работы и потребления ресурсов. В процессе жизни в системе процесс непосредственно управляется специальными системными вызовами, которые обеспечивают его построение передачу - управления - завершение:
fork - exec - exit — совокупность этих переключений состояний процесса определяет время существования процесса.
В общем случае активный процесс (выполняемая задача) может находиться в одном из шести состояний (в Linux):
1.ожидание процессора в очереди
2.выполнение на процессоре в течение выделенного кванта времени;
3.ожидание освобождения ресурса (например - устройства);
4.приостановлен специальным сигналом;
5.завершился, но его дескриптор еще в оперативной памяти ядра ОС;
6.процесс свопирован на внешнюю память.
В активном состоянии находится несколько процессов — до 30000. Каждому процессу выделяется виртуальная память практически без ограничений (за счет страничной организации). При выполнении любого вычислительного задания прикладные и системные процессы ядра должны взаимодействовать между собой. Это необходимо для обмена данными, для передачи управляющей информации при использовании системных ресурсов, для синхронизации или управления последовательностью выполнения процессов и т.д.
Для этих целей служат специальные системные программы, встроенные в оболочку и поддерживающие следующие механизмы взаимодействия процессов:
программы-сокеты - для обмена данными;
программные каналы для обмена данными между утилитами (см. выше);
асинхронные сигналы - ключевые слова, передаваемые от одного процесса к другому, например, для завершения выполнения процесса или для получения информации о свершении некоторых событий в системе (сигнал от таймера, ошибка при передаче данных на устройство, попытка выполнения несуществующей команды и пр );
семафоры - синхронизация выполнения процессов посредством установки значений бит "флагов" - специальных системных переменных;
совместно используемая общая область физической памяти;
Перечисленные механизмы использует как сама ОС (write,mail и пр.), так и прикладные программы с помощью команд управления процессами или системных вызовов.
Рассмотрим создание и работу процессов на примере процедуры.
Так как sh-процедура — исполняемый файл, то процесс его выполнения обеспечивается в ОС обычными механизмами построения и управления процессами. Для каждой sh-процедуры строится свой процесс со своим дескриптором — порожденный процесс. В дескрипторе процесса хранится информация, необходимая ядру для управления процессом. Дискрипторы хранятся в адресном пространстве ядра ОС в виде двунаправленного приоритетного списка, упорядоченного в соответствии с их номерами - идентификаторами процессов (PID).
Пример:
$ vi ргос
date
Is
$sh ргос
< дата>
f2
$
Рассмотрим, как реализуются процессы процедуры примера.
В ответ на приглашение -$ вводится имя процедуры ргос и создастся порожденный процесс shell. Он вводит данные, необходимые для своего выполнения из указанного файла ргос — командные строки. Каждая команда sh-процсдуры выполняется порожденным для неё процессом (как обычно для команды, введенной с клавиатуры — процессы утилит). Как только все команды окажутся выполненными, sh-процссс завершается и управление возвращается родительскому процессу . Процедура выполнена.
Планировщик обрабатывает процессы двух видов - обычные и более приоритетные процессы реального времени. Место в очереди определяется его приоритетом.
Процессы выполняются в одном из двух режимов — пользовательском и в режиме ядра. В режиме ядра выполняются процессы системных вызовов. В этом случае они имеют доступ к процедурам и структурам данных ядра. Такая организация позволяет ядру защитить свои процедуры и структуры системных данных от искажений со стороны проблемных задач.
Дескрипторы процессов создаются и удаляются динамически при выполнении процессов. Поэтому состав и размер списка постоянно меняются. Так как все процессы связаны между собой родственными отношениями, то списковая организация процессов используется для процессов одного ранга (например, для всех порожденных одним родительским или для всех родительских и.тд.). Таким образом, вся система дескрипторов представляет собой некоторую древовидную структуру с коренным обще системным процессом (swapper - имеющего идентификатор РID=0), который компилируется в состав ядра и используется для построения всей структуры дескрипторов и обработки. Открывается очередь наиболее приоритетным процессом инициатора ОС (init - PID=1), который строится первым при инициализации ОС и уничтожается при завершении работы ОС.
Процессор выделяется каждому процессу в очереди на выполнение ограниченные кванты времени в отличие от однозадачного режима (DOS), где процессор выделяется процессам последовательно на все время выполнения процесса. Это принципиально отличает многозадачный режим обработки заданий в UNIX. В UNIX пересчет приоритетов происходит постоянно по прерываниям определенного типа с частотой — около одного раза в секунду.
Часть информации дескриптора может быть выведена в листинг характеристик процесса с помощью специальной команды ps. Некоторые заголовки полей листинга:
номер терминала, которому принадлежит процесс (TTY);
приоритет (PRI);
использованное время процессора (STIME);
идентификатор процесса (PID);
имя программы процесса или команды, выполняемой в теле процедуры на момент запроса листинга (CMD);
идентификатор родительского процесса (PPID);
адрес процесса (ADDR);
величина изменения значения приоритета (NI) и пр.
Для вывода листинга процессов, принадлежащих пользователю можно воспользоваться конструкцией: $ ps -f | grep [имя пользователя].
Для управления состоянием процессов при оперативной работе можно использовать сочетание управляющих клавиш. При одновременном нажатии их в ВС вырабатывается прерывание определенного типа, которое и приводит к изменению состояний процессов (как прикладных, так и системных):
ctrl+S — «зависает» активный процесс диалога с пользователем;
ctrl+Q — продолжить выполнение процесса:
ctrl+D — конец набора текста с клавиатуры;
ctrl+Z — приостановка активного процесса:
ctrl+C — выход из утилиты.
Полную информацию о процессе пользователь или администратор может получить с помощью команды ps. По умолчанию эта команда выводит информацию о процессах пользователя данного терминала.
$ ps [-к] [имя пользователя>] #вывод листинга характеристик процесса.
Некоторые значения ключей:
-а — показать процессы данного терминала:
-af — полный (достаточный) формат сообщения:
-al — длинный формат;
-u — показать все активные процессы данного пользователя;
-А —показать все активные процессы.
Пример:$ ps -flu [имя пользователя]
СОЗДАНИЕ ФОНОВЫХ ПРОЦЕССОВ
При обычном запуске с терминала некоторой программы на исполнение (системной утилиты или прикладной задачи) интерпретатором shell создастся привилегированный процесс, который все время связан со своим терминалом. Запуск следующего процесса может быть выполнен пользователем только после завершения текущего, при появлении приглашения '$' от интерпретатора.
В целях использования возможности параллельного выполнения программ в ОС UNIX отдельные задачи или задания пакетного режима могут быть запущены одновременно с заданиями диалогового режима. Для запуска фонового (параллельного с другими потомками) процесса в командную строку необходимо и достаточно последним символом добавить знак & (амперсанд) амперсанд , действует так же, как точка с запятой или разделитель строк, за исключением того, что этот символ указывает оболочке, что не следует ждать завершения команды.:
Shell выводит номер этого процесса (PID) и разрешает ввод следующей команды.
Фоновые процессы обладают некоторыми недостатками:
не допускают ввода с клавиатуры
обеспечивают вывод на экран, но при этом нарушают целостность вывода диалогового процесса
Общепринятый прием исключения влияния фонового вывода на интерактивную работу:
$ [командная_строка] > имя_файлa.out &
[командная_строка] планирует задание для фонового режима; > перенаправляет вывод вместо экрана в указанный файл головного каталога пользователя.
Пример: $ grep ааа* > grep.сс &
PROCFS
procfs — виртуальная файловая система, используемая в UNIX-подобных операционных системах. Позволяет получить доступ к информации из ядра о системных процессах. Необходима для выполнения таких команд как ps, w, top. Обычно её монтируют на /proc. procfs создает двухуровневое представление пространств процессов. На верхнем уровне процессы представляют собой директории, именованные в соответствии с их pid. Также на верхнем уровне располагается ссылка на директорию, соответствующую процессу, выполняющему запрос; она может иметь различное имя в различных ОС (curproc во FreeBSD, self в Linux).
/proc LINUX
В LINUX procfs изначально представляла универсальный интерфейс получения информации от ядра, а не только о процессах. В корне содержатся файлы (в основном, текстовые) и каталоги, предоставляющие самые разнообразные сведения о системе. В то же время, свою первоначальную функцию — управление процессами — procfs почти не выполняет. Интерфейс отправки команд отсутствует, файловая система лишь предоставляет подробную информацию о процессах (и кое-где позволяет изменить некоторые опции, например, /proc/<pid>/oom_adj)
Компоненты для создания и выполнения процесса под общим названием proc. >> Перевод статьи Federico Kereki «Discover the possibilities of the /proc directory»:
Директория /proc — странный зверь. Она не существует на самом деле, но вы можете заглянуть в неё. Её файлы нулевой длины не являются ни бинарными, ни текстовыми, но вы можете открыть и просмотреть их. Эта специальная директория хранит все детали о вашей системе Linux, включая её ядро, процессы и параметры конфигурации. Изучая директорию /proc, вы можете изучить, как работают команды Linux, и даже сможете делать некоторые задачи администрирования.
В Linux все представлено в виде файла; даже к устройствам доступ происходит, как к файлам (в директории /dev). Не смотря на то, что вы можете подумать, что «нормальные» файлы либо текстовые, либо бинарные (или, возможно, файлы устройств или конвейеров), директория /proc содержит файлы странного типа, — виртуальные файлы. Их можно вывести списком, но на самом деле, они не существуют на диске; операционная система создает их «на лету», если вы делаете попытку их прочитать.
Большинство виртуальных файлов всегда имеют текущую метку даты/времени, говорящую о том, что они постоянно поддерживаются в рабочем состоянии. Директория /proc создается сама по себе каждый раз при загрузке системы. Вам нужно работать с правами суперпользователя, чтобы просмотреть всю директорию; некоторые из файлов (например, связанные с процессами) принадлежат пользователю, запустившему их. Хотя большинство файлов доступны только для чтения, несколько доступных для записи (в особенности в /proc/sys) позволяют вам менять параметры ядра (конечно, вы должны быть осторожны, делая это).
Организация директории /proc
Директория /proc состоит из виртуальных директорий и поддиректорий, которые группируют файлы по определенному принципу. Работая под суперпользователем, команда ls /proc выдаст что-то вроде этого:
1 2432 3340 3715 3762 5441 815
129 2474 3358 3716 3764 5445
1290 248 3413 3717 3812 5459
133 2486 3435 3718 3813 5479
1420 2489 3439 3728 3814 557
165 276 3450 3731 39 5842
166 280 36 3733 3973 5854
2 2812 3602 3734 4 6
2267 3 3603 3735 40 6381
2268 326 3614 3737 4083 6558
2282 327 3696 3739 4868 6561
2285 3284 3697 3742 4873 6961
2295 329 3700 3744 4878 7206
2335 3295 3701 3745 5 7207
2400 330 3706 3747 5109 7222
2401 3318 3709 3749 5112 7225
2427 3329 3710 3751 541 7244
2428 3336 3714 3753 5440 752
devices modules
acpi diskstats mounts
asound dma mtrr
bus execdomains partitions
dri fb self
driver filesystems slabinfo
fs interrupts splash
ide iomem stat
irq ioports swaps
net kallsyms sysrq-trigger
scsi kcore timer_list
sys keys timer_stats
sysvipc key-users uptime
tty kmsg version
buddyinfo loadavg vmcore
cmdline locks vmstat
config.gz meminfo zoneinfo
cpuinfo misc
Пронумерованные директории (остановимся на них позже) соответствуют каждому запущенному процессу; специальная символьная ссылка self указывает на текущий процесс. Некоторые виртуальные файлы предоставляют информацию о аппаратном обеспечении, например, /proc/cpuinfo, /proc/meminfo и /proc/interrupts. Другие дают информацию, связанную с файлами, например, /proc/filesystems или /proc/partitions. Файлы в /proc/sys относятся к конфигурации параметров ядра, как мы увидим позже.
Команда cat /proc/meminfo может дать следующее:
# cat /proc/meminfo
MemTotal: 483488 kB
MemFree: 9348 kB
Buffers: 6796 kB
Cached: 168292 kB
...несколько строк пропущены...
Если вы попробуете команды top или free, вы можете узнать некоторые из этих чисел. Фактически, несколько хорошо известных утилит получают доступ к директории /proc, чтобы получить информацию. Например, если вы хотите узнать, какую версию ядра вы используете, вы можете попробовать uname -srv или спуститься к истокам и набрать cat /proc/version. Есть ещё несколько других интересных файлов:
— /proc/apm: содержит информацию о Advanced Power Management, если она установлена.
— /proc/acpi: похожая директория, дающая хорошую информацию про более современный ACPI. К примеру, чтобы узнать, подключен ли ваш ноутбук к питанию AC, вы можете выполнить cat /proc/acpi/ac_adapter/AC/state и получить либо «on line», либо «off line»
— /proc/cmdline: Показывает параметры, переданные ядру при загрузке. В моем случае, это root=/dev/disk/by-id/scsi-SATA_FUJITSU_MHS2040_NLA5T3314DW3-part3 vga=0x317 resume=/dev/sda2 splash=silent PROFILE=QuintaWiFi, что говорит о том, какой раздел файловой системы является основным, какой режим VGA используется и так далее. Последний параметр сделан с помощью Системы управления настройкой провилей openSUSE.
— /proc/cpuinfo: Дает данные о процессоре вашего компьютера. Например, на моем ноутбуке, команда cat /proc/cpuinfo выводит листинг, начинающийся с:
processor : 0
vendor_id : AuthenticAMD
cpu family : 6
model : 8
model name : Mobile AMD Athlon(tm) XP 2200+
stepping : 1
cpu MHz : 927.549
cache size : 256 KB
Демонстрирующий, что у меня есть только один процессор, под номером 0, семейства 80686 (6 в cpu family идет в качестве средней цифры), — AMD Athlon XP, работающий минимум на 1 Гц.
— /proc/loadavg: Файл, показывающий среднюю загрузку процессора; его информация включает использование ЦПУ в последнюю минуту, последние пять минут и последние 10 минут, а также число процессов, работающих в данный момент.
— /proc/stat: Также предоставляет статистику, но последней загрузки.
— /proc/uptime: Короткий файл, в котором только два числа — сколько секунд ваша система работает и сколько секунд она простаивает.
— /proc/devices: Показывает все настроенные и загруженные символьные и блочные устройства. /proc/ide и /proc/scsi дает данные об устройствах IDE и SCSI.
— /proc/ioports: Показывает информацию о зонах, используемых для ввода-вывода с вышеуказанными устройствами.
— /proc/dma: Показывает используемые каналы DMA.
— /proc/filesystems: Показывает типы файловых систем, поддерживаемых вашим ядром. Вот как это может выглядеть:
nodev sysfs
nodev rootfs
nodev bdev
nodev proc
nodev cpuset
...несколько строк пропущено...
nodev ramfs
nodev hugetlbfs
nodev mqueue
ext3
nodev usbfs
ext2
nodev autofs
Первая колонка показывает, какая файловая система монтирована на блочное устройство. В моем случае, у меня есть разделы, настроенные с смонтированными ext2 и ext3.
— /proc/mounts: Показывает всё смонтированное, что используется вашим компьютером (его вывод очень похож на /etc/mtab). Проще говоря, /proc/partitions и /proc/swaps покажет все разделы и пространство swap.
— /proc/fs: Если вы открываете общий доступ к файловым системам с помощью NFS, в этой директории среди множества поддиректорий и файлов, есть /proc/fs/nfsd/exports, который показывает файловую систему, открытую для общего доступа и права на неё.
— /proc/net: Содержит сетевую информацию. Описание каждого из файлов в этой директории займет слишком много места, но в ней есть /dev (каждое сетевое устройство), несколько файлов, связанных с iptables, сетевая статистика и статистика портов, информация о беспроводных подключениях и так далее.
Есть также несколько файлов, связанных с ОЗУ. Я уже упомянул о /proc/meminfo, но у вас также есть /proc/iomem, который показывает, сколько памяти использует ваша система и /proc/kcore, демонстрирующий физическую оперативную память ваше системы. В отличие от большинства других виртуальных файлов, размер /proc/kcore соответствует размеру вашей оперативной памяти и даже немного больше (не пытайтесь выполнить cat /proc/kcore, так как он имеет бинарное содержимое и завалит ваш экран). Наконец, здесь же есть много файлов и директорий, связанных с аппаратным обеспечением, такие как /proc/interrupts и /proc/irq, /proc/pci (все устройства PCI), /proc/bus и так далее, но они включают в себя очень специфическую информацию, которая не нужна большинству пользователей.
Что с процессами?
Как я и сказал ранее, директории, имена который пронумерованы, представляют все запущенные процессы. Когда процесс завершается, его директория в /proc исчезает автоматически. Если вы проверите любую из этих директорий во время их существования, вы обнаружите множество файлов, таких как:
attr cpuset fdinfo
auxv cwd loginuid
clear_refs environ maps
cmdline exe mem
coredump_filter fd mounts
mountstats stat
oom_adj statm
oom_score status
root task
smaps wchan
Давайте изучим основные файлы:
— cmdline: Содержит команду, запустившую процесс, со всеми её параметрами.
— cwd: Символьная ссылка на текущую рабочую директорию (CWD) процесса; exe ссылается на исполняемый процесс, а root на его корневую директорию.
— environ: Показывает все переменные окружения процесса.
— fd: Содержит все файловые дескрипторы для процесса, показывающие, какие файлы или устройства он использует.
— maps, statm и mem: Работают с памятью, используемой процессом.
— stat и status: Предоставляют информацию о статусе процесса, но последний — более четкую и упорядоченную.
Эти файлы дают несколько возможностей для написания скриптов. Например, если вы хотите отследить процессы-зомби, вы можете пройти по всем пронумерованным директориям и проверить содержание строки «(Z) Zombie» в файле /status. Однажды мне надо было проверить, запущена ли определенная программа. Я сделал проход по директориям и проверил файлы /cmdline, в поисках необходимой строки (вы также можете сделать это с помощью команды ps, но в этой статье это не рассматривается). А если вы хотите написать top, который будет выглядеть лучше, вся необходимая информация в ваших руках.
Настройка системы: /proc/sys
/proc/sys не только дает информацию о системе, она также позволяет изменять параметры ядра «на лету», активируя и дезактивируя его возможности (конечно, это может принести и вред вашей системе, — будьте осторожны!). Чтобы определить, какой файл для настройки, а какой только для чтения, выполните ls -ld. Если файл имеет аттрибут «W», это значит, что вы можете использовать его каким-либо образом для настройки ядра. К примеру, ls -ld /proc/kernel/* начинается примерно так:
dr-xr-xr-x 0 root root 0 2008-01-26 00:49 pty
dr-xr-xr-x 0 root root 0 2008-01-26 00:49 random
-rw-r--r-- 1 root root 0 2008-01-26 00:49 acct
-rw-r--r-- 1 root root 0 2008-01-26 00:49 acpi_video_flags
-rw-r--r-- 1 root root 0 2008-01-26 00:49 audit_argv_kb
-r--r--r-- 1 root root 0 2008-01-26 00:49 bootloader_type
-rw------- 1 root root 0 2008-01-26 00:49 cad_pid
-rw------- 1 root root 0 2008-01-26 00:49 cap-bound
Как видете, bootloader_type не может быть изменен, но остальные файлы могут. Чтобы изменить файл, используйте что-то вроде echo 10 >/proc/sys/vm/swappiness. Конкретно этот пример позволит вам настроить производительность страничной организации виртуальной памяти. Кстати, эти изменения — временные и их результаты будут отменены при перезагрузке. Используйте sysctl и файл /etc/sysctl.conf, чтобы сделать более постоянные изменения.
Давайте поверхностно посмотрим на директории в /proc/sys:
— debug: Содержит (сюрприз!) отладочную информацию. Это полезно, если вы занимаетесь разработкой ядра.
— dev: Предоставляет информацию о специфических устройствах в вашей системе. Например, проверьте директорию /dev/cdrom.
— fs: Дает данные о каждом возможном аспекте файловой системы.
— kernel: Позволяет вам затрагивать работу и настройки ядра напрямую.
— net: Допускает вас до вопросов, связанных с сетью. Будьте осторожны, потому как запутавшись в этом, вы можете потерять подключение.
— vm: Работает с подсистемой VM.
Заключение
Специальная директория /proc предоставляет детальную информацию о внутренней работе Linux и позволяет вам улучшить многие аспекты его настройки. Если вы потратите немного больше времени, изучая все возможности этой директории, вы сможете получить более совершенную систему Linux. А не этого ли мы все желаем
Особенности работы с фоновым режимом:
выполняемая в фоновом режиме программа (команда), требующая стандартного ввода, должна читать его из файла с использованием перенаправленного ввода;
— Программа, выполняемая в фоновом режиме, не может быть прервана Ctrl+C, так как она отсоединяется от клавиатуры и может быть прекращена только с помощью команды kill или выходом из системы выход из системы exit надо выполнять два раза: для завершения фонового процесса и завершения основного процесса shell.
— В случаях, когда фоновый процесс все же требует ввода данных с клавиатуры, то его надо временно перевести в оперативный режим, ввести данные, и вернуть опять в фоновый с помощью следующих команд: fg , bg (foreground -передний план background -задний план), вы не найдете справки по командам fg и bg (man fg, man bg). Потому, что эти команды являются частью bash. И упоминание о них вы найдете в man bash, а синтаксис такой:
fg %N — перевод фонового процесса в оперативный;
bg %N — перевод оперативного в фоновый режим.
Здесь N — порядковый номер фонового задания, которое в общем случае может содержать несколько активных процессов и все они переводятся в соответствующий режим.
Номер задания “N” выводится: при запуске фоновой программы командой jobs без приостановления или с приостановлением фонового процесса
Приостановить текущий foreground процесс, выполняемый в терминале, с выходом в shell (например, для анализа состояния и результатов работы процедуры) можно с помощью прерывания, ctrl+Z
При этом процесс станет фоновым и освободит терминал для выполнения других команд. Чтобы продолжить выполнение процесса в фоновом режиме, нужно просто выполнить команду bg.
Пример:
$ inf > f.out & #запуск процедуры inf в фоновом режиме;
[1] 1754 # номер задания и идентификатор процесса;
$ jobs
%1 #номер задания фоновой задачи;
$ fg %l #перевод из фонового в оперативный;
ctrl+Z #приостанов оперативного процесса;
[1]+stopped inf > f.out
$ fg %l #продолжение оперативного (бывшего фонового);
$ bg %1 #возврат процесса в фоновый режим;
[1] inf>f.out.
Выполнение фоновых заданий прекращается с выходом пользователя из системы. НО! Если фоновая программа должна быть продолжена и после прекращения текущего сеанса работы, то необходимо использовать команду: nohup [имя фоновой программы] & команда,
во-первых, запускает и защищает фоновую программу от прерываний, вырабатываемых при выходе пользователя из системы ( от сигнала SIGHUP, который посылает своим дочерним процессам, процесс-родитель, когда завершает свою работу, при закрытии терминала или выходе из консоли, команда также прекратит свою работу.)
во- вторых, перенаправляет фоновый протокол в системный файл nohup.out.(По умолчанию все выходные данные nohup-задания направляются в файл nohup.out, но вы можете указать любой другой файл:)
Пример 1. nohup перенаправляет протокол в указанный файл: $ nohup команда > файл_вывода 2>&1 & В данном случае к потоку вывода присоединяется ещё и поток сообщений об ошибках (2>&1). Предположим, что у нас есть некоторый скрипт script.sh, который должен выполняться даже после того, как мы выходим из текущего сеанса командной оболочки. Проверим, как это работает:
$ nohup ./script.sh &
nohup: ввод игнорируется, вывод добавляется в 'nohup.out'
[2] 5111
$
Если сейчас посмотреть таблицу процессов, то увидим, что скрипт выполняется как обычный фоновый процесс с привязкой к терминалу:
$ ps x | grep script
5111 pts/0 RN 0:07 /bin/sh ./script.sh
5178 pts/0 S+ 0:00 grep script
В третьем столбце указан статус процесса: R – процесс выполняется, N – признак понижения приоритета, что характерно для большинства nohup-заданий. В четвёртом столбце – суммарное время использования процессора.
Теперь выйдем из командной оболочки, выполнив команду logout (exit) или просто закрыв окно терминала, затем снова запустим сеанс shell и введём ещё раз команду просмотра процессов:
$ ps x | grep script
5111 ? RN 2:18 /bin/sh ./script.sh
5283 pts/1 S+ 0:00 grep script
Идентификатор процесса остался неизменным (5111), а вот во втором столбце появился знак вопроса, обозначающий отсутствие связи данного процесса с каким-либо терминалом. Судя по четвёртому столбцу, наш скрипт даром времени не терял и продолжал свою работу. Пример 2:
$ nohup find / -user [….] -type f &
$ nohup: ввод игнорируется, вывод добавляется в «nohup.out»
$cd #переход в HOME
$cat nohup.out #Протокол команды find
Команда nohup позволяет таким образом предупредить вывод на экран протокола фонового задания с прерыванием протокола работы оперативного процесса. Команду nohup можно использовать, но есть приложения с которыми она не срабатывает. Например, браузер Opera. Набрав, nohup opera & и закрыв терминал, Opera также завершит свою работу.
В оболочке bash есть подобная nohup встроенная команда, которая больше подходит для требуемой задачи. Это команда disown. Приложения запущенные в терминале в фоне (приложения запущенные со знаком &), являются задачами или заданиями, которые формируют таблицу заданий. При выходе из терминала bash просматривает эту таблицу и посылает всем заданиям сигнал SIGHUP. Команда disown занимается тем, удаляет задания из таблицы заданий. Посмотреть информацию о команде disown можно в справке man bash. На всякий случай вот фрагмент из справки:
disown [-ar] [-h] [jobspec …]
и пример с Opera:
$ opera &
$ disown #после чего терминал можно закрыть Opera останется.
дескриптор файла -- это просто число, по которому система идентифицирует открытые файлы. Рассматривайте его как упрощенную версию указателя на файл.
УПРАВЛЕНИЕ ПРИОРИТЕТАМИ ПРОЦЕССОВ
Максимальный приоритет процессов каждого пользователя группы устанавливает администратор. Если при выполнении задания образуются несколько порожденных процессов, то вес они имеют одинаковый приоритет равный родительскому. В этом случае все процессы получают ресурсы равными долями (простой режим разделения времени). При необходимости выделения наиболее важных родительских процессов порожденным второстепенным можно понизить приоритет с помощью команды: nice [-к] [имя программы] — выполнение программы, указанной в строке, с пониженным приоритетом. -к — коэффициент понижения приоритета (k = 1..>..0; по умолчанию к = 10). Пример:
$ cat &
[1] 5400
$ ps -al
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 T 1000 5400 5373 0 80 0 - 2109 signal pts/8 00:00:00 cat
0 R 1000 5401 5373 0 80 0 - 2811 - pts/8 00:00:00 ps
т.е. процесс имет приоритет, равный 80.
$ nice -10 cat &
[2] 5428
$ ps -flu [user]
F S PID PPID C PRI NI ADDR SZ WCHAN STIME TTY
0 T 5400 5373 0 80 0 - 2109 signal 23:35 pts/8
0 T 5428 5373 0 90 10 - 2109 signal 23:36 pts/8
0 R 5430 5373 0 80 0 - 4919 - 23:36 pts/8
Приоритет процесса задачи cat (PID5428) понижен на 10 единиц, тем самым другие процессы этой группы имеют больше возможностей в использовании ресурсов. Чем больше число, тем ниже приоритет.
ЗАВЕРШЕНИЕ ПРОЦЕССОВ
Завершение процессов - одна из функций управления процессами. Прекратить выполнение любого процесса можно с помощью команды: kill
# kill [-опции] [PID1] [PID2....]— передает сигнал процессу PID.
Сигнал — ключевое понятие UNIX, при получении которого процесс выполняет некоторые действия. Сигналы с использованием команды kill могут передаваться другими прикладными процессами или системными программами (например, при появлении некоторых событий, как то сбой в канале, сигнала с таймера, завершения фонового процесса и пр.). Существуют двадцать пять видов сигналов, предназначенных для выполнения различных действий процессами при наступлении определенных событий в системе. С получением большинства сигналов процесс завершается самостоятельно. Тот, кто посылает сигнал, должен быть владельцем процесса или администратором. Для безусловного и немедленного завершения указанного процесса kill должен послать сигнал с именем SIGTERM (по умолчанию -15). Другие сигналы передаются с помощью опции -S. Значения опций:
# kill -S [имя сигнала] или [№ — системный номер сигнала]
# kill -l #вывод на экран справочника имен сигналов.
Сигнал определяет дальнейшее действие процесса. Это еще один способ управления процессами. Пример:
# kill -9 3752
3752: killed
Пример завершения фонового процесса:
# kill %1 — указывается номер завершаемого задания
[I] +Terminated inf
Если процесс указан идентификатором Ø, то команда kill уничтожает все процессы, связанные с текущим shell (завершается головной процесс swapper (имеющий РID=Ø) и все связанные с ним порожденные процессы shell, прикладные задачи).
ПЕРЕХВАТЫВАНИЕ СИГНАЛОВ
В процедурах управления процессами особое место занимает обработка прерываний команда: trap (ловушка) [список команд или имя sh-процедуры] [сигнал 1][сигнал 2] Захватить эти сигналы достаточно легко, и команда ловушка имеет следующий синтаксис:
$ trap [commands] [signals]
Команда перехватывает указанные сигналы и последовательно выполняет все команды списка, прежде чем поступивший сигнал будет передан процессу. Например, команда может быть использована для синхронизации заданий, если надо выполнить какие-то действия с файлами, а затем уже завершить процесс, или могут быть ситуации, когда вы не захотите, чтобы пользователи ваших скриптов с помощью ввода на клавиатуре специальной последовательности клавиш несвоевременно выходили из скрипта, например, поскольку нужно освободить входной поток или стереть ненужные данные. Инструкция trap перехватывает эти последовательности и ее можно так запрограммировать, что при обнаружении этих сигналов будет выполнен список команд.
Команде trap указывается перехватить перечисленные сигналы [signals], которые могут быть именами сигналов с префиксом SIG или без этого префикса, либо номерами сигналов. Если сигнал равен Ø или EXIT, команды [commands] выполняются тогда, когда происходит выход в командную оболочку. Если одним из сигналов является сигнал DEBUG, список команд [commands] выполняется после выполнения каждой простой команды. Сигнал может быть также определен как ERR, в этом случае команды [commands] выполняются каждый раз, когда выход из простой команды происходит с ненулевым кодом возврата. Обратите внимание, что эти команды не будут выполняться, если ненулевой код возврат будет возвращен из части инструкции if или из цикла while или until. Они не будут исполняться даже в случае, когда с помощью логических команд AND (&&) или OR (||) будет возвращен ненулевой код выхода, или когда код возврата команды инвертируется с помощью оператора !.
Если спецификации сигнала были указаны правильно, то код возврата самой команды trap равен нулю. В команде trap есть несколько параметров, которые описаны в документации по Bash.
Пример перехвата Ctrl+C, вводимого пользователя, при котором печатается сообщение. При попытке уничтожить эту программу без указания сигнала KILL, ничего происходить не будет:
#!/bin/bash
# traptest.sh
trap "echo Booh!" SIGINT SIGTERM
echo "pid is $$"
while : # This is the same as "while true".
do
sleep 60 # This script is not really doing anything.
done
Как Bash интерпретирует команду trap
Когда во время ожидания завершения команды Bash принимает сигнал, для которого была установлена команда trap, команда trap не будет выполняться до завершения исполняемой команды. Когда Bash с помощью встроенной команды wait ожидает выполнение асинхронной команды, прием сигнала, для которого была задана команда trap, вызовет немедленный выход из встроенной команды wait с кодом возврата, большим 128, а затем сразу будет выполнена команда trap.
Применение команды trap может быть самым разнообразным. Но глубокое её изучение требует предварительного знания всего списка сигналов и их назначения, а также наиболее часто встречающихся типовых применений trap.