Процессы

"Процесс - одно из фундаментальнейших понятий операционной системы 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 Лекция 6  UNIX Лекция 7  UNIX Лекция 8  UNIX Лекция 9

Модель процесса

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

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

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

В условиях многозадачности каждый процесс имеет свою управляющую логику (то есть логический счетчик команд) идущую (идущие) не зависимо друг от друга. Разумеется, на самом деле существует только один физический счетчик команд, в который загружается логический счетчик команд текущего процесса. Когда время, отведенное текущему процессу, заканчивается, физический счетчик команд сохраняется в логическом счетчике команд процесса в памяти.

 Программы и процессы

Обычно программой называют совокупность файлов, будь то набор исходных текстов, объектных файлов или собственно выполняемый файл. Для того чтобы программа могла быть запущена на выполнение, операционная система сначала должна создать окружение или среду выполнения задачи, куда относятся ресурсы памяти, возможность доступа к устройствам ввода/вывода и различным системным ресурсам, включая услуги ядра. Это окружение (среда выполнения задачи) получило название процесса. Мы можем представить процесс как совокупность данных ядра системы, необходимых для описания образа программы в памяти и управления ее выполнением. Мы можем также представить процесс как программу в стадии ее выполнения, поскольку все выполняющиеся программы представлены в UNIX в виде процессов. Процесс состоит из инструкций (~команд), выполняемых процессором (совокупность отдельных операций процессора, определенных единой системой команд), данных и информации о выполняемой задаче, такой как размещенная память, открытые файлы и статус процесса.

С каждым процессом связывается его адресное пространство — список адресов в памяти от некоторого минимума (обычно нуля) до некоторого максимума, которые процесс может прочесть и в которые он может писать. Адресное пространство содержит саму программу, данные к ней и ее стек. Со всяким процессом связывается некий набор регистров, то есть памяти внутри процессора, соответственно памяти "сверхбыстрой"  включая счетчик команд, указатель стека и другие аппаратные регистры, плюс вся остальная информация, необходимая для запуска программы. 

В то же время не следует отождествлять процесс с программой хотя бы потому, что программа может породить более одного процесса. (Программа — согласно ГОСТ 19781­90 — данные, предназначенные для управления конкретными компонентами системы обработки информации в целях реализации определённого алгоритма.) Простейшие программы, например,  whoили cat, при выполнении представлены только одним процессом. Сложные задачи, например системные серверы (печати, FTP, Telnet), порождают в системе несколько одновременно выполняющихся процессов. Операционная система UNIX является многозадачной. Это значит, что одновременно может выполняться несколько процессов, причем часть процессов могут являться образцами одной программы. Различие между процессом и программой трудноуловимо и тем не менее имеет принципиальное значение.

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

Типы процессов

Системные процессы

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

К системным процессам следует отнести 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) идентификаторы пользователя

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


Реальный (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/

http://rus-linux.net/consol/exec-in-command-find

https://unix.stackexchange.com/how-to-run-find-exec

Если сделать "отпечаток" выполняемых процессов, например командой 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.(здесь)

$ pstree

Выше представлен "стандартный" процесс загрузки операционных систем семейства *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 возвращает идентификатор созданного дочернего процесса, а дочерний процесс получает значение, равное Ø.

Для отправления сигнала служит команда killkill [sig_no]  [pid] где: 

  sig_nо — номер или символическое название сигнала

  pid        — идентификатор процесса, которому посылается сигнал.

Администратор системы может посылать сигналы любым процессам, обычный же пользователь может посылать сигналы только процессам, владельцем которых он является (реальный и эффективный идентификаторы процесса должны совпадать с идентификатором пользователя). Например, чтобы послать процессу, который вы только что запустили в фоновом режиме, сигнал завершения выполнения SIGTERM, можно воспользоваться командой:

$ my_program &      #Запустим программу в фоновом режиме

$ kill $!           #По умолчанию команда kill посылает сигнал SIGTERM;

                    #переменная $! содержит PID последнего процесса, запущенного в

                    #фоновом режиме


При получении сигнала процесс имеет три варианта действий для выбора:


По умолчанию команда kill посылает сигнал с номером -15sigterm, действие по умолчанию для которого — завершение выполнения процесса, получившего сигнал.Иногда процесс продолжает существовать и после отправления сигнала 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 

ЭТО попробует убить их всех (если получится)


Сигналы могут не только использоваться для завершения выполнения процессов, но и иметь специфическое для приложения (обычно для системных демонов) значение (естественно, это не относится к сигналам SIGKILL и SIGSTOP). Например, отправление сигнала SIGHUP (HangUP) серверу имен DNS (named) вызовет считывание базы данных с диска. Для других приложений могут быть определены другие сигналы и соответствующие им значения.

 commandlinefu.com

Соответствие между символьными именами и номерами сигналов может отличаться в различных версиях UNIX. 

Команда kill -l выводит номера сигналов и их имена...............читать ЭТО!, и это здорово , еще лучше прочесть:

Морис Дж. Бах - "Архитектура операционной системы UNIX"  ТУТ

Забродин Л.Д Операционная система UNIX ст. 64-76       <<---PDF

http://citforum.ru/operating_systems/unix

ПРОЦЕССЫ В UNIX

УПРАВЛЕНИЕ ПРОЦЕССАМИ

UNIX — многопользовательская многозадачная операционная система. Концепция процесса является базовой для архитектуры ОС. Процесс строится для каждой прикладной (например, sh- процедуры) и системной задачи (например, утилиты) с помощью системного вызова fork. Является единицей вычислительной работы и потребления ресурсов. В процессе жизни в системе процесс непосредственно управляется специальными системными вызовами, которые обеспечивают его построение передачу - управления - завершение:

fork - exec - exit — совокупность этих переключений состояний процесса определяет время существования процесса.

В общем случае активный процесс (выполняемая задача) может находиться в одном из шести состояний (в Linux):

В активном состоянии находится несколько процессов — до 30000. Каждому процессу выделяется виртуальная память практически без ограничений (за счет страничной организации). При выполнении любого вычислительного задания прикладные и системные процессы ядра должны взаимодействовать между собой. Это необходимо для обмена данными, для передачи управляющей информации при использовании системных ресурсов, для синхронизации или управления последовательностью выполнения процессов и т.д.

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

Перечисленные механизмы использует как сама ОС (write,mail и пр.), так и прикладные программы с помощью команд управления процессами или системных вызовов.

Рассмотрим создание и работу процессов на примере процедуры.

Так как sh-процедура — исполняемый файл, то процесс его выполнения обеспечивается в ОС обычными механизмами построения и управления процессами. Для каждой sh-процедуры строится свой процесс со своим дескриптором — порожденный процесс. В дескрипторе процесса хранится информация, необходимая ядру для управления процессом. Дискрипторы хранятся в адресном пространстве ядра ОС в виде двунаправленного приоритетного списка, упорядоченного в соответствии с их номерами - идентификаторами процессов (PID).

Пример:

$ vi ргос

date

Is

$sh ргос

< дата>

f2

$

Рассмотрим, как реализуются процессы процедуры примера.

В ответ на приглашение -$ вводится имя процедуры ргос и создастся порожденный процесс shell. Он вводит данные, необходимые для своего выполнения из указанного файла ргос — командные строки. Каждая команда sh-процсдуры выполняется порожденным для неё процессом (как обычно для команды, введенной с клавиатуры — процессы утилит). Как только все команды окажутся выполненными, sh-процссс завершается и управление возвращается родительскому процессу . Процедура выполнена.

Планировщик обрабатывает процессы двух видов - обычные и более приоритетные процессы реального времени. Место в очереди определяется его приоритетом.

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

Дескрипторы процессов создаются и удаляются динамически при выполнении процессов. Поэтому состав и размер списка постоянно меняются. Так как все процессы связаны между собой родственными отношениями, то списковая организация процессов используется для процессов одного ранга (например, для всех порожденных одним родительским или для всех родительских и.тд.). Таким образом, вся система дескрипторов представляет собой некоторую древовидную структуру с коренным обще системным процессом (swapper - имеющего идентификатор РID=0), который компилируется в состав ядра и используется для построения всей структуры дескрипторов и обработки. Открывается очередь наиболее приоритетным процессом инициатора ОС (init - PID=1), который строится первым при инициализации ОС и уничтожается при завершении работы ОС.

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

Часть информации дескриптора может быть выведена в листинг характеристик процесса с помощью специальной команды ps. Некоторые заголовки полей листинга:

 Для вывода листинга процессов, принадлежащих пользователю можно воспользоваться конструкцией: $ ps -f | grep [имя пользователя].

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

ctrl+S — «зависает» активный процесс диалога с пользователем;

ctrl+Q — продолжить выполнение процесса:

ctrl+D — конец набора текста с клавиатуры;

ctrl+Z — приостановка активного процесса:

ctrl+C — выход из утилиты.

Полную информацию о процессе пользователь или администратор может получить с помощью команды ps. По умолчанию эта команда выводит информацию о процессах пользователя данного терминала.

$ ps [-к] [имя пользователя>]            #вывод листинга характеристик процесса.

Некоторые значения ключей:

      — показать процессы данного терминала:

-af    — полный (достаточный) формат сообщения:

-al   — длинный формат;

-u      — показать все активные процессы данного пользователя;

      —показать все активные процессы.

Пример:$ ps -flu [имя пользователя]

СОЗДАНИЕ ФОНОВЫХ ПРОЦЕССОВ

При обычном запуске с терминала некоторой программы на исполнение (системной утилиты или прикладной задачи) интерпретатором shell создастся привилегированный процесс, который все время связан со своим терминалом. Запуск следующего процесса может быть выполнен пользователем только после завершения текущего, при появлении приглашения '$' от интерпретатора.

В целях использования возможности параллельного выполнения программ в ОС UNIX отдельные задачи или задания пакетного режима могут быть запущены одновременно с заданиями диалогового режима. Для запуска фонового (параллельного с другими потомками) процесса в командную строку необходимо и достаточно последним символом добавить знак & (амперсанд)  амперсанд , действует так же, как точка с запятой или разделитель строк, за исключением того, что этот символ указывает оболочке, что не следует ждать завершения команды.:

http://www.ibm.com

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  [имя фоновой программы] & команда, 

Пример 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.

НИТИ И ПРОЦЕССЫ

Процессы и нити в ОС Linux