<<
>>

Управление процессами в UNIX

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

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

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

В этом случае родительский процесс выполняет системный вызов wait или waitpid, в результате чего он временно приостанавливается и ждет, пока дочерний процесс не выполнит системный вызов exit.

Процессы могут выполнять вызов fork сколь угодно часто, в результате чего получается целое дерево процессов. Посмотрите на рис. 6.29. Здесь процесс А выполнил вызов fork дважды и породил два новых процесса, В и С. Затем процесс В тоже выполнил вызов fork дважды, а процесс С — один раз. Таким образом, получилось дерево из шести процессов.

Рис.

6.29. Дерево процессов в системе UNIX

Процессы в и№Х могут взаимодействовать друг с другом через специальную информационную структуру, которая называется каналом. Канал представляет собой вид буфера, в который один процесс записывает поток данных, а другой процесс извлекает оттуда эти данные. Байты всегда возвращаются из канала в том порядке, в котором они были записаны. Случайный доступ невозможен. Каналы не сохраняют границ между фрагментами данных, поэтому если один процесс записал в канал 4 фрагмента по 128 байт, а другой процесс считывает данные по 512 байт, то второй процесс получит все данные сразу без указания на то, что они были записаны за несколько приемов.

В System V и Solaris применяется другой метод взаимодействия процессов. Здесь используются так называемые очереди сообщений. Процесс может создать новую очередь сообщений или открыть уже существующую с помощью вызова msgget. Для отправки сообщений используется вызов msgsnd, а для получения — msgrecv. Сообщения, отправленные таким способом, отличаются от данных, помещаемых в канал. Во-первых, границы сообщений сохраняются, в то же время канал просто передает поток данных. Во-вторых, сообщения имеют приоритеты, поэтому срочные сообщения идут перед всеми остальными. В-третьих, сообщения типизированы, и вызов msgrecv позволяет определять их тип, если это необходимо.

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

Еще одна особенность System V и Solaris — наличие семафоров. Принципы их работы мы уже описывали, когда говорили о производителе и потребителе.

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

Эти потоки управления обычно называют просто программными потоками. Они похожи на процессы, которые делят общее адресное пространство и все объекты, связанные с этим адресным пространством (дескрипторы файлов, переменные окружения и т. д.). Однако каждый поток имеет собственный счетчик команд, собственные регистры и собственный стек. Если один из программных потоков приостанавливается (например, пока не завершится процесс ввода-вывода), другие программные потоки в том же процессе могут продолжать работу. Два программных потока в одном процессе, которые действуют как процесс-производитель и процесс-потребитель, напоминают два однопоточных процесса, которые разделяют сегмент памяти, содержащий буфер, хотя не идентичны им. Во втором случае каждый процесс имеет собственные дескрипторы файлов и т. д., тогда как в первом случае все эти элементы общие. В примере взаимодействия производителя и потребителя мы видели, как работают потоки в Java. Иногда для поддержки каждого из программных потоков исполняющая система Java использует программный поток операционной системы, однако это не обязательно.

В каких случаях могут понадобиться программные потоки? Рассмотрим веб-сервер. Такой сервер может хранить в основной памяти кэш часто используемых веб-страниц. Если нужная страница находится в кэш-памяти, то она выдается немедленно. Если нет, то она вызывается с диска. К сожалению, на это требуется довольно длительное время (обычно 20 миллисекунд), на это время

процесс блокируется и не может обслуживать вновь поступающие запросы, даже если запрашиваемые веб-страницы находятся в кэш-памяти.

Для решения проблемы можно создать несколько программных потоков в одном процессе, которые разделяют общую кэш-память веб-страниц. Если один из программных потоков блокируется, новые запросы могут обрабатываться другими программными потоками. Предотвратить блокировку процессов можно и без использования программных потоков. Для этого потребуется несколько процессов, но тогда придется продублировать кэш, а это несколько расточительно, поскольку объем памяти ограничен.

Стандарт системы 1Ж1Х на программные потоки называется рПпгеасЬ и определяется в Р081Х (Р1003.1С).

Он описывает вызовы для управления программными потоками и их синхронизации. В стандарте ничего не сказано о том, должно ли управлять программными потоками ядро, или они должны функционировать только в пользовательском пространстве. Наиболее распространенные функции для работы с программными потоками приведены в табл. 6.9.
Таблица 6.9. Основные функции для работы с программными потоками, определенные в стандарте РОЭ1Х
Функция Описание
рЩгеас1_сгеа1е Создание нового программного потока в адресном пространстве вызывающей процедуры
рШгеас!_ехй Завершение программного потока
рЩгеасУот Ожидание завершения программного потока
рЩгеас1_тШех_тй Создание нового мьютекса
рЩгеас1_тШех_с1е81гоу Удаление мьютекса
рЩ геас!_т Шех_1 ос к Блокирование мьютекса
рШгеас1_т1Дех_ип1оск Разблокирование мьютекса
рЩгеа^сопсИпй Создание условной переменной
рЩгеас1_сопс1_с1е5Цоу Удаление условной переменной
рЩгеас1_сопс1_\л/ай Ждет условную переменную
рШгеас1_сопс1_81дпа1 Разблокирование одного из программных потоков, ожидающего условной переменной

Давайте рассмотрим эти вызовы. Первый вызов, р1:11геас1_сгеа1е, создает новый программный поток.

После выполнения этой процедуры в адресном пространстве появляется на один программный поток больше. Программный поток, который выполнил свою работу, вызывает функцию р1:11геас1_ех11:. Если потоку нужно подождать, пока другой поток окончит работу, он вызывает функцию р1:11геас1_о(лп. Если этот другой программный поток уже закончил свою работу, вызов р1:11геас1з(лп немедленно завершается. В противном случае он блокируется.

Программные потоки можно синхронизировать с помощью специальных объектов, которые называются мьютексами (пн^ехез). Обычно мьютекс управляет каким-либо ресурсом (например, буфером, разделенным между двумя программными потоками). Для того чтобы в конкретный момент времени только один поток мог получать доступ к общему ресурсу, потоки должны блокировать мьютекс перед использованием ресурса и разблокировать его после завершения работы с ним. Так можно избежать состояния гонок, поскольку этому протоколу подчиняются все программные потоки. Мьютексы похожи на бинарные семафоры (то есть семафоры, которые могут принимать только два значения: 0 или 1).

Мьютексы можно создавать и разрушать вызовами pthreadmutexinit и pthreadmutexdestroy соответственно. Мьютекс может находиться в одном из двух состояний: заблокированном и незаблокированном. Если программному потоку нужно заблокировать ^заблокированный мьютекс, он выполняет вызов pthread_ mutexlock, а затем продолжает работу. Однако если программный поток попытается заблокировать уже заблокированный мьютекс, поток приостанавливается. Когда поток, который в данный момент использует общий ресурс, завершит работу с этим ресурсом, он должен разблокировать соответствующий мьютекс вызовом pthreadmutexunl ock.

Мьютексы предназначены для кратковременной блокировки (например, для защиты общей переменной), но не предназначены для длительной синхронизации (например, для ожидания, пока освободится накопитель на магнитной ленте). Для длительной синхронизации существуют условные переменные (condition variables). Эти переменные создаются и удаляются вызовами pthreadcondinit и pthreadconddestroy соответственно.

Условная переменная связана с двумя программными потоками: ожидающим и сигнальным. Если, например, программный поток обнаруживает, что накопитель на магнитной ленте, который ему нужен, в данный момент занят, этот поток выполняет для условной переменной вызов pthreadcondwait. Когда поток, который использует накопитель на магнитной ленте, завершает свою работу с этим устройством (а это может произойти через несколько часов), он сигнализирует об этом вызовом pthreadcondsignal. Это позволяет разблокировать ровно один поток — тот, который ожидает эту условную переменную. При отсутствии программных потоков, ожидающих эту переменную, сигнал пропадает. У условных переменных нет счетчика, как у семафоров. Отметим, что с потоками, мьютексами и условными переменными можно выполнять и некоторые другие операции.

<< | >>
Источник: Таненбаум Э.. Архитектура компьютера. 5-е изд. 2007

Еще по теме Управление процессами в UNIX:

  1. Поведенческая основа процесса управления.
  2. Сущность процесса управления в организациях.
  3. РАЗДЕЛ III. СОЦИОЛОГИЧЕСКОЕ ОБЕСПЕЧЕНИЕ ПРОЦЕССОВ УПРАВЛЕНИЯ СОЦИАЛЬНОЙ СФЕРОЙ
  4. Психологические особенности управления инновационным процессом в правоохранительных органах.
  5. Психологические особенности управления инновационным процессом в правоохранительных органах.
  6. Статья 1040. Обращение взыскания на имущество, переданное в управление, по требованию кредитора установщика управления
  7. Очерк 2: Берт «Процесс — вот мое достояние. Именно процесс создает успех»
  8. § 3. Право управления предприятием как особый вид абсолютных прав. Право полного и ограниченного управления (п. 1774-1776)
  9. УПРАВЛЕНИЕ ВРЕМЕНЕМ VERSUS УПРАВЛЕНИЕ СОБОЙ
  10. § 4. Правопреемство как следствие приобретения права управления предприятием. Условия отчуждения и приобретения права управления предприятием (п. 1777-1782)
  11. Задания, мешающие когнитивному процессу (ЗМКП), и задания, помогающие когнитивному процессу (ЗПКП)
  12. Функции управления в организации.
  13. Управление термами
  14. Управление деканатами