
- •Статические и динамические библиотеки (сборка и использование)
- •Автоматизация сборки приложений с помощью make
- •Создание процессов, системные вызовы fork и exec(см.Файлик)
- •Процессы демоны, создание процессов демонов Демоны и потоки
- •Структуры данных процесса
- •Идентификационные данные процесса
- •Контекст процесса
- •Состояния процессов
- •Другие параметры процесса
- •Режимы выполнения процессов
- •Средства межпроцессорного взаимодействия
- •Методы межпроцессного взаимодействия
- •[Править]Реализации
- •Проблемы межпроцессного взаимодействия
- •Обмен информацией между процессами
- •Сигналы
- •Разделяемая память
- •Семафоры, системные вызовы для работы с семафорами
- •Семафоры
- •3.1. Использование семафоров
- •3.2. Создание множеств семафоров
- •3.3. Управление семафорами
- •3.3.1. Использование semctl
- •Очереди сообщений, системные вызовы для работы с очередями сообщений
- •2.1. Использование очередей сообщений
- •2.2. Создание очередей сообщений
- •2.2.1. Использование msgget
- •Разделяемая память, системные вызовы для работы с разделяемой памятью
- •4.1. Использование разделяемых сегментов памяти
- •4.2. Создание разделяемых сегментов памяти
- •4.3. Управление разделяемыми сегментами памяти
- •4.3.1. Использование shmctl
Разделяемая память
Самый простой способ «обойти» разделение виртуальных пространств процессов — использование разделяемой памяти. Это специальный механизм, с помощью которого средствами операционной системы два процесса могут обращаться к общему участку физической памяти — каждый через свое адресное пространство.
Для операционной системы этот способ является наиболее простым — ведь все страницы виртуальной памяти процессов в любом случае проецируются на какую-то область физической памяти — так почему бы на ту же область не проецировать часть адресного пространства другого процесса? Самое важное, что такое взаимодействие не требует каких-либо накладных расходов, процессы обмениваются информацией со скоростью обращения к памяти.
Однако для пользователя такой способ межпроцессного взаимодействия является труднодоступным. Во-первых, программы, взаимодействующие таким образом, должны изначально содержать соответствующий код — с помощью специальных системных вызовов обе программы должны обозначить участки своих адресных пространств, предназначенные для обмена информацией. Другая сложность состоит в том, что разделяемая память сама по себе не содержит средств синхронизации, программы должны согласованно изменять общий участок памяти, чтобы не испортить данные; обычно для этих целей применяются семафоры и аналогичные механизмы синхронизации. Эту проблему мы осветим чуть ниже.
Таким образом, разделяемая память — наиболее быстрый способ обмена, но при этом малопригодный для широкого использования. Обычная сфера применения разделяемой памяти — специализированные высокопроизводительные программы. Стоит также обратить внимание на явную аналогию разделяемой памяти и исполнения множества потоков в рамках одного процесса — в UNIX эти инструменты построения программ используются редко и только в связи с высокопроизводительными вычислениями и вводом-выводом.
Вызовы POSIX — shmem(), mmap().
Семафоры, системные вызовы для работы с семафорами
Семафоры, собственно говоря, не являются средством передачи данных. Они выполняют в межпроцессорном взаимодействии вспомогательную роль и служат для организации одновременного использования разделяемых данных несколькими процессами. Если два процесса читают один набор данных и выполнение процессов — последовательное, то это, очевидно, не создает проблем. Если же два процесса пытаются изменить один и тот же набор данных, то результат уже будет зависеть от того, в какой последовательности выполняется считывание и запись этих данных. Для управления такими процессами и вводятся семафоры.
В простейшем случае семафор представляет собой просто счетчик, содержащий 0 или единицу. Значение счетчика, равное 1, означает доступность соответствующего ресурса (например, файла или страницы виртуальной памяти). Если же в счетчике 0, значит, ресурс занят, и операция недопустима.
В общем случае семафор представляет собой не один счетчик, а группу из нескольких счетчиков, причем каждый счетчик может принимать не только значения 0 и 1, а любое значение из определенного интервала. Чаще всего число в семафоре представляет собой количество процессов, которые могут получить доступ к данным. Каждый раз, когда процесс обращается к данным, значение в семафоре, должно быть уменьшено на единицу, и увеличено, когда работа с данными будет прекращена. Семафоры можно использовать и для других целей, например, для счётчика ресурсов. В этом случае число в семафоре — количество свободных ресурсов (например, количество свободных ячеек памяти).
Семафоры должны быть доступны различным процессам, поэтому они размещаются в адресном пространстве ядра и операции с ними осуществляются через интерфейс системных вызовов.
Системные вызовы для работы с семафорами
Ниже приведен обзор системных вызовов для работы с семафорами:
semget(2) Этот системный вызов получает набор из одного или
более семафоров. semget(2) возвращает идентификатор
набора семафоров. Семафор однозначно определяется
этим идентификатором и индексом (начинающимся с
нуля) в наборе.
semclt(2) Этот системный вызов служит следующим целям:
. Получает значение одиночного семафора из набора
или всех семафоров в наборе.
. Устанавливает значение одного или всех семафоров
в наборе.
. Получает информацию о состоянии набора семафоров.
. Определяет число процессов, ожидающих, пока
семафор из набора не станет нулевым.
. Определяет число процессов, ожидающих, пока
семафор в наборе не увеличится по сравнению с его
текущим значением.
. Определяет процесс, который выполнял последнюю
операцию над семафором.
. Удаляет набор семафоров. Наборы семафоров, так же
как файлы и очереди сообщений, должны удаляться
явным образом.
semop(2) Этот системный вызов оперирует с одним или
несколькими семафорами в наборе. Можно увеличить
значение семафора на заданную величину, уменьшить,
или ожидать, пока значение семафора не станет
нулевым. Уменьшение значения семафора блокирует
процесс, если вычитаемая величина меньше его
текущего значения.
. semget(2)
- создать набор из одного или нескольких семафоров, или
получить доступ к существующему набору.
. semctl(2)
- получить или установить значение одного или всех семафоров
в наборе
- получить информацию о состоянии или изменить состояние
набора семафоров
- определить количество процессов, ожидающих нулевого
значения семафора или увеличения его текущего значения
- определить процесс, который выполнил последнюю операцию над
семафором
- удалить набор семафоров
. semop(2)
- выполнить операцию над одним или несколькими семафорами из
набора