7.1. Средства взаимодействия процессов в Unix

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

  • передачи данных между процессами;
  • совместного использования данных;
  • извещения о наступлении каких-либо событий.

Средствами взаимодействия между процессами являются:

  • сигналы;
  • неименованные каналы;
  • именованные каналы;
  • сообщения;
  • семафоры (определяют доступ к ресурсам);
  • разделимая память;
  • сокеты (средство взаимодействия процессов хостов в сети). [1]

7.2 Программные каналы и семафоры

Программные каналы. Традиционным средством взаимодействия и синхронизации процессов в ОС UNIX являются программные каналы (pipes). Теоретически программный канал позволяет взаимодействовать любому числу процессов, обеспечивая дисциплину FIFO (first-in-first-out). Другими словами, процесс, читающий из программного канала, прочитает те данные, которые были записаны в программный канал наиболее давно. В традиционной реализации программных каналов для хранения данных использовались файлы. В современных версиях ОС UNIX для реализации программных каналов применяются другие средства.

Различаются два вида программных каналов - именованные и неименованные. Именованный программный канал может служить для общения и синхронизации произвольных процессов, знающих имя данного программного канала и имеющих соответствующие права доступа. Неименованным программным каналом могут пользоваться только создавший его процесс и его потомки (необязательно прямые). [1]

Именованные каналы отличаются от неименованных наличием имени, то есть идентификатора канала, потенциально видимого всем процессам системы. Для идентификации именованного канала создается файл специального типа pipe. Файлы именованных каналов создаются функцией mkfifo().

Именованный канал можно создать системным вызовом mknod (namefile, IFIFO|0666, 0), namefile - имя канала; 0666 - к каналу разрешен доступ на запись и на чтение любому запросившему процессу.

Пример создания именованного канала:

						$ mkfifo namefile
						$ cat > namefile – запись в именованный канал
						12345
						$ cat namefile – чтение из именованного канала. [2]

					

Конвейеры (неименованные каналы) соответствуют оригинальным конвейерам программ: набор процессов, связаны своими стандартными потоками ввода-вывода таким образом, что выходной поток каждого процесса (stdout) непосредственно связывается со стандартным потоком ввода (stdin) следующего. Конвейер обозначается |.

Пример: ls | grep “rwx” – перенаправление вывода команды ls на ввод команды grep. [3]

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

Есть два типа семафоров:

1. Семафор со счетчиком (countingsemaphore), определяющий лимит ресурсов для процессов, получающих доступ к ним.

Смысл семафора со счетчиком в том, чтобы дать доступ к какому-то ресурсу только определенному количеству процессов. Остальные будут ждать в очереди, когда ресурс освободится.

2. Бинарный семафор (binarysemaphore), имеющий два состояния «0» или «1» (чаще: «занят» или «не занят»).

Термин «бинарный семафор» употребляется для описания конструкции, которая ограничивает доступ к одному ресурсу. То есть бинарный семафор используют там, где один процесс «занимает» семафор, а другой его «освобождает». [4]

7.3. Сигналы

Сигналы - способ передачи информации от одного процесса к другому или от ядра ОС к любому процессу. Сигналы обеспечивают механизм вызова определенной процедуры при наступлении некоторого события (аналогично прерываниям). Каждое событие имеет свой числовой идентификатор (обычно в диапазоне от 1 до 36) и соответствующую символьную константу - имя. Сигналы хранятся в виде мнемонической формы записи в файле .

При работе с сигналами необходимо различать две фазы:

  1. генерация или посылка сигнала;
  2. доставка и обработка сигнала.

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

Сигнал может посылаться одним процессом другому (с помощью соответствующего системного вызова) и будет доставлен, если оба процесса - одного пользователя, или сигнал послан от имени пользователя root. Сигналы посылаются также ядром.

Ядро генерирует и посылает процессу сигнал в ответ на ряд событий, которые могут быть вызваны самим процессом, другим процессом, прерыванием или каким либо внешним событием. Основные причины отправки сигнала:

  • Исключительные ситуации. Выполнение процесса вызывает исключительную ситуацию, например, деление на 0.
  • Терминальные прерывания. Нажатие клавиш терминала, например: Del, Ctrl+C, Ctrl+\; вызывает посылку сигнала текущему процессу, связанному с терминалом.
  • Другие процессы. Процесс может посылать сигнал другому процессу или группе процессов с помощью системного вызова kill. В этом случае сигналы являются элементарной формой межпроцессного взаимодействия.
  • Управление заданиями. Командные интерпретаторы, поддерживающие средства управления заданиями, используют сигналы для манипулирования фоновыми и текущими процессами. Когда процесс, выполняющийся в фоновом режиме, делает попытку чтения или записи на терминал, ему посылается сигнал остановки. Когда порожденный процесс завершает свою работу, родительский процесс уведомляется об этом также с помощью сигнала.
  • Квоты. Когда процесс превышает выделенную ему квоту вычислительных ресурсов или ресурсов файловой системы, ему посылается соответствующий сигнал.
  • Уведомления. Процесс может запросить уведомление о наступлении тех или иных событий, например, готовности устройства и т.д. Такое уведомление посылается процессу в виде сигнала.
  • Будильники. Если процесс установил таймер, ему будет послан сигнал, когда значение таймера станет равным 0.

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

Основные сигналы приведены в таблице 7.1.

Таблица 7.1 – Основные сигналы в UNIX

Сигнал

Стандартная обработка

Значение

SIGTERM
15

Завершение процесса

Стандартный сигнал, посылаемый для остановки процесса.

SIGINT

2

Завершение процесса

Закончить процесс. Посылается всем процессам при нажатии определённых клавиш <Delete>, <Ctrl-C>.

SIGHUP
1

Завершение процесса

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

SIGKILL
9

Завершение процесса

Не перехватываемый сигнал, позволяющий завершить любой процесс.

SIGILL
4

Завершение процесса и сброс образа памяти

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

SIGTRAP
5

Завершение процесса и сброс образа памяти

Была установлена ловушка точки прерывания процесса. Этим управляет системный вызов ptrace, который полезен для отладки.

SIGFPE
8

Завершение процесса и сброс образа памяти

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

SIGBUS
10

Завершение процесса и сброс образа памяти

Ошибка на шине ввода-вывода. Обычно это является результатом попытки выполнить чтение или запись вне границ памяти программы.

SIGSEGV
11

Завершение процесса и сброс образа памяти

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

SIGPIPE
13

Завершение процесса

Программа попыталась выполнить чтение или запись в программный канал, другой конец которого уже завершил работу. Этот сигнал помогает завершить работу конвейера, когда одна из его команд дала сбой.

SIGALARM
14

Завершение процесса

Будильник, позволяющий в определенный момент времени выполнить какое-нибудь действие.

SIGCHLD
18

Игнорируется

Сначала это был сигнал завершения работы дочернего процесса, но сейчас он означает изменение состояния дочернего процесса.

SIGTSTOP
24

Остановка процесса

Это запрос от терминала на остановку процесса. Посылка этого сигнала процессу происходит при нажатии комбинации клавиш Ctrl-Z.

SIGCONT
25

Игнорируется

Этот сигнал указывает процессу на возобновление его работы. Процессу посылается либо команда fg, либо bg, а командный интерпретатор выполняет внутренний системный вызов wait для привилегированного процесса, либо не выполняет его для фонового процесса.

Средством посылки сигнала служит команда kill -№sign PID. По умолчанию kill посылает SIGTERM. [5]

7.4. Команды управления процессами

Для работы с процессами используются следующие команды:

1) ps – вывод информации о запущенных процессах.

Ключи: a - процессы, связанные с текущим терминалом, и процессы других пользователей;

x - процессы, отсоединённые от терминала (демоны, службы);

aux - вывод всех процессов в системе;

-ejH - вывод процессов в виде дерева;

-u user - процессы пользователя user;

-о format – вывод информации в определённом формате.

Пример: ps –eo pid,cmd – вывести PID и имена всех процессов системы.

2) nohup команда – позволяет игнорировать сигнал SIGHUP (команда продолжает выполняться после выхода из системы). Результат выполнения команды сохранится в файле nohup.out.

3) nice -n value команда - изменение приоритета запускаемого процесса команда на значение, равное value (может быть от -20 до 19, в порядке уменьшения приоритета).

4) renice -value PID - изменение приоритета запущенного процесса с PID на значение, равное value.

Пример: renice +5 1248 – понижение приоритета процесса с номером 1248 на 5.

5) jobs - список остановленных и фоновых задач.

6) bg number - продолжить выполнение остановленной задачи в фоне, имеющей номер number (указан в выводе jobs).

7) fg number – перевести задачу с номером number из фонового режима в активный.

8) top - показать все запущенные процессы в интерактивном режиме.

Клавиши для управления командой:

  • h - справка о программе;
  • k - уничтожить процесс;
  • n - число отображаемых процессов;
  • u - сортировать по имени пользователя;
  • M - сортировать по объему ОЗУ;
  • P - сортировать по загрузке ЦП;
  • r - изменить приоритет выполнения;
  • q – выход.

9) pstree - отобразить дерево процессов:

Ключи:

  • р – показывает PID процессов;
  • u – показывает имя пользователя, запустившего процесс.

Источники:

1. CIT forum. Взаимодействие процессов. – URL: http://citforum.ru/operating_systems/unix/glava_23.shtml

2. Life-prog.ru. Именованные каналы (FIFO). – URL: http://life-prog.ru/1_46978_imenovannie-kanali-FIFO.html

3. Life-prog.ru. Конвейер в Unix. – URL: http://life-prog.ru/view_unix.php?id=8

4. Знакомство с межпроцессным взаимодействием на Linux. – URL: https://habr.com/ru/post/122108/

5. CIT forum. Основы операционной системы UNIX. – URL: http://citforum.ru/operating_systems/unix/kravchuk/7.shtml