Виды межпроцессного взаимодействия - WEBSITE X5 UNREGISTERED VERSION 12.0.5.22 - Электронный справочник по дисциплине Операционные системы и среды

Перейти к контенту

Главное меню:

Межпроцессное взаимодействие
Межпроцессное взаимодействие


Виды межпроцессного взаимодействия (IPC)
  • Передача информации от одного процесса другому
  • Предотвращение критических ситуаций
  • Синхронизация процессов
  • Межпроцессное взаимодействие
     Предотвращение критических ситуаций и средства синхронизации процессов
     Возникновение гонок (состязаний)
     Два процесса хотят получить доступ к общей памяти в одно и тоже время.
     Рассмотрим пример межпроцессного взаимодействия на примере спулера печати.
     Если процессу требуется вывести на печать файл, он помещает имя файла в специальный каталог спулера.
     Другой процесс, “демон печати”, периодически проверяет наличие файлов, которые нужно печатать, печатает файл и удаляет его имя из каталога.
     Представим, что каталог спулера состоит из большого числа сегментов, нумерованных 0,1, 2…, в каждом из которых может храниться имя файла. Также есть две совместно используемые переменные: out, указывающая на следующий файл для печати, иin, указывающая на следующий свободный сегмент.
     Эти две переменные можно хранить в одном файле, доступном для всех процессов. Пусть в данный момент времени сегменты с 0 по 3 пусты (файлы уже напечатаны), а сегменты 4-6 заняты (файлы ждут печати).
     Более или менее одновременно процессы AиBрешают поставить файл в очередь на печать.
     Возможна следующая ситуация:
     Процесс Aсчитывает значение (7) переменнойinи сохраняет его в локальной переменнойnext_free_slot. После этого происходит прерывание по таймеру, и процессор переключается на процессB. ПроцессB, в свою очередь, считывает значение переменнойinи сохраняет его (опять 7) в своей локальной переменнойnext_free_slot.
     Теперь оба процесса считают, что следующий свободный сегмент – седьмой.
    Процесс Bсохраняет в каталоге спулера имя файла и заменяет значениеinна 8, затем продолжает заниматься своими задачами, не связанными с печатью.
     Наконец управление переходит к процессу A, и он начинает с того места, на котором остановился. Он обращается к переменнойnext_free_slot, считывает ее значение и записывает в седьмой сегмент имя файла (удаляя значение, записанное процессомB).
     В результате файл процесса Bне напечатается.
    Критические секции
    • Важным понятием синхронизации потоков для решения проблемы состязаний является понятие «критической секции» программы.
    • Критическая секция – это часть программы, результат выполнения которой может непредсказуемо меняться, если переменные, относящиеся к этой части программы, изменяются другими потоками в то время, когда выполнение этой части еще не завершено.
  • Во всех потоках, работающих с критическими данными, должна быть определена критическая секция.
  • В разных потоках критическая секция состоит в общем случае из разных последовательностей команд.
  •  Самый простой и в то же время самый неэффективный способ обеспечения взаимного исключения состоит в том, что операционная система позволяет потоку запрещать любые прерывания на время его нахождения в критической секции. Однако этот способ практически не применяется, так как опасно доверять управление системой пользовательскому потоку — он может надолго занять процессор, а при крахе потока в критической секции крах потерпит вся система, потому что прерывания никогда не будут разрешены.
    Условия исключения гонок
    • Два процесса не должны одновременно находиться в критической секции
    • В программе не должно быть предположений о скорости или количестве процессоров
  •  Процесс вне критической секции не может блокировать другие процессы
  • Должна быть невозможна ситуация, когда процесс вечно ждет попадания в критическую секцию.
  • Семафоры
    • Дийкстра (Dijkstra) предложил использовать переменные, которые могут принимать целые неотрицательные значения. Такие переменные, используемые для синхронизации вычислительных процессов, получили название семафоров.
    • Семафор - неотрицательная целая переменная S >= 0, которая может изменяться и проверяться только посредством двух примитивов:
    • V(S): переменная S увеличивается на 1 единым неделимым действием. К переменной S нет доступа другим потокам во время выполнения этой операции.
  • P(S): уменьшение S на 1, если это возможно. Если S=0 и невозможно уменьшить S, оставаясь в области целых неотрицательных значений, то в этом случае поток, вызывающий операцию Р, ждет, пока это уменьшение станет возможным. Успешная проверка и уменьшение также являются неделимой операцией.
  • Иллюстрация работы семафора
     Данный пример демонстрирует использование семафора для ограничения доступа потоков к объекту синхронизации на основании их количества.
    Задача о читателях и писателях
    • Рассмотрим использование семафоров на классическом примере взаимодействия двух выполняющихся в режиме мультипрограммирования потоков, один из которых пишет данные в буферный пул, а другой считывает их из буферного пула.
    • Пусть буферный пул состоит из N буферов, каждый из которых может содержать одну запись. В общем случае поток-писатель и поток-читатель могут иметь различные скорости и обращаться к буферному пулу с переменой интенсивностью. В один период скорость записи может превышать скорость чтения, в другой – наоборот.
  • Для правильной совместной работы поток-писатель должен приостанавливаться, когда все буферы оказываются занятыми, и активизироваться при освобождении хотя бы одного буфера. Напротив, поток-читатель должен приостанавливаться, когда все буферы пусты, и активизироваться при появлении хотя бы одной записи.
  • Введем два семафора: е – число пустых буферов, и f – число заполненных буферов, причем в исходном состоянии е =N, a  f =0. Тогда работа потоков с общим буферным пулом может быть описана следующим образом.
    • Таким образом, семафоры позволяют эффективно решать задачу синхронизации Доступа к ресурсным пулам, таким, например, как набор идентичных в функциональном назначении внешних устройств (модемов, принтеров, портов), или набор областей памяти одинаковой величины, или информационных структур. Во всех этих и подобных им случаях с помощью семафоров можно организовать доступ к разделяемым ресурсам сразу нескольких потоков.
    Мьютексы
    • Иногда используется упрощенная версия семафора – мьютекс (mutex,mutualexclusion– взаимное исключение). Иногда называют еще двоичным семафором.
    • Мьютекс – переменная, которая может находиться в одном из двух состояний: блокированном или неблокированном.
  • Если процесс хочет войти в критическую секцию – он вызывает примитив блокировки мьютекса.
  • Если мьютекс не заблокирован, то запрос выполняется и процесс попадает в критическую секцию.
  • Использование мьютекса
     В рассмотренном примере, для того чтобы исключить коллизии при работе с разделяемой областью памяти, будем считать, что запись в буфер и считывание из буфера являются критическими секциями. Взаимное исключение будем обеспечивать с помощью двоичного семафора (мьютекса) b. Оба потока после проверки доступности буферов должны выполнить проверку доступности критической секции.
    Мониторы
    • Для упрощения написания программ в 1974 г. Хоар (Hoare) и Бринч (BrinchHansen) предложили примитив синхронизации более высокого уровня – монитор.
    • Монитор – примитив синхронизации более высокого уровня.
  • Монитор – набор процедур, переменных и других структур данных, объединенных в особый модуль.
  • Пользовательские процессы могут вызывать процедуры монитора, но не могут получать доступ к внутренним структурам.
  • Реализации взаимных исключений способствует важное свойство монитора – при обращении к монитору в любой момент времени может быть активен только один процесс. Реализация взаимного исключения реализуется с помощью мьютекса.
  • Поскольку реализацию взаимного исключения выполняет компилятор, а не программист, вероятность ошибки уменьшается.
  • Решение задачи читателей и писателей с помощью монитора
    Межпроцессное взаимодействие
    Синхронизация потоков с использованием объектов ядра Windows2000
    Синхронизация потоков
    • При работе параллельного приложения, его потокам часто требуется способ связи друг с другом для координации своих действий. Пример такой связи - передача данных через каналы. Однако простейшей формой связи является синхронизация (synchronization).
    • Синхронизация означает способность потока добровольно приостанавливать свое исполнение и ожидать, пока не завершится выполнение некоторой операции другим потоком.
  • Все ОС, поддерживающие многозадачность или мультипроцессорную обработку, должны предоставлять потокам способ ожидания того, что другой поток что–либо сделает: например, освободит накопитель на магнитном диске или закончит запись в совместно используемый буфер памяти. ОС должна также дать потоку возможность сообщить другим потокам об окончании выполнения операции. Получив такое уведомление, ожидающий поток может продолжить выполнение.
  • Объекты синхронизации и их состояния
    • процессы
    • потоки
  • задания
  • файлы
  • консольный ввод
  • уведомления об изменении файлов
  • события
  • ожидаемые таймеры
  • семафоры
  • мьютексы
  •  Когда объект свободен, флажок поднят, а когда он занят, флажок опущен.
    • Средства ожидания и сообщения реализованы в ядре Win2000 как часть объектной архитектуры.
    • Синхронизационные объекты (synchronization objects) – это объекты ядра, при помощи которых поток синхронизирует свое выполнение.
  • В любой момент времени синхронизационный объект находится в одном из двух состояний: (signaled state) или занят.
  • Правила, по которым объект переходит в свободное или занятое состояние, зависят от типа этого объекта.
  • Объект-поток находится в состоянии «занят» все время существования, но устанавливается системой в состояние "свободен", когда его выполнение завершается. Аналогично, ядро устанавливает процесс в состояние "свободен", когда завершился его последний поток. В противоположность этому, объект – таймер «срабатывает» через заданное время (по истечении этого времени ядро устанавливает объект – таймер в состояние "свободен").
  • Спящие потоки
     Потоки спят, пока ожидаемые ими объекты заняты (флажок опущен). Как только объект освободился (флажок поднят), спящий поток замечает это, просыпается просыпается и возобновляет выполнение.
    Функции ожидания
    DWORD WaitForSingleObject(
    HANDLE hObject,
    DWORD dwMilliseconds
    );
    DWORD WaitForMultipleObjects(
    DWOHD dwCount,
    CONST HANDLE* phObjects,
    BOOL fWaitAll,
    DWORD dwMilliseconds
    );
    WaitForSingleObject (hProcess, INFINITE);
    • Wait-функции позволяют потоку в любой момент приостановиться и ждать освобождения какого-либо объекта ядра.
    • Когда поток вызывает эту функцию, первый параметр, hObject, идентифицирует объект ядра, поддерживающий состояния «свободен-занят» (То есть любой объект, упомянутый в списке из предыдущего раздела.) Второй параметр,dwMilliseconds, указывает, сколько времени (в миллисекундах) поток готов ждать освобождения объекта.
  • Следующий вызов сообщает системе, что поток будет ждать до тех пор, пока не завершится процесс, идентифицируемый описателем hProcess.
  • Функция WaitForMultipleObjects аналогичнаWaitForSingleObject c тем исключением, что позволяет ждать освобождения сразу нескольких объектов или какого-то одного из списка объектов.
  • Параметр dwCount определяет количество интересующих Вас объектов ядра Его значение должно быть в пределах от 1 до MAXIMUM_WAIT_OBJECTS (в заголовочных файлах Windows оно определено как 64). ПараметрphObject— это указатель на массив описателей объектов ядра.
  • WaitForMultipleObjects приостанавливает поток и заставляет его ждать освобождения либо всех заданных объектов ядра, либо одного из них. ПараметрfWaitAllкак раз и определяет, чего именно Вы хотите от функции. Если он равен TRUE, функция не даст потоку возобновить свою работу, пока не освободятся все объекты.
  • Объекты синхронизации
    • События
    • Ожидаемый таймер
  • Семафор
  • Мьютекс
  • События
    • События – самая примитивная разновидность объектов ядра.
    • События содержат счетчик числа пользователей (как и все объекты ядра) и две булевы переменные: одна сообщает тип данного объекта-события, другая – его состояние (свободен или занят).
  • События просто уведомляют об окончании какой-либо операции. Объекты-события бывают двух типов: со сбросом вручную (manual-reset events) и с автосбросом (auto-reset events). Разница в том, что первый вид события нужно применять если событие ждут несколько потоков. Только сброс вручную позволяет это сделать. Иначе первый же обработчик сбросит событие и другие потоки об этом не узнают.
  • Объекты-события обычно используют в том случае, когда какой-то поток выполняет инициализацию, а затем сигнализирует другому потоку, что тот может продолжить работу. Инициализирующий поток переводит объект "событие” в занятое состояние и приступает к своим операциям. Закончив, он сбрасывает событие в свободное состояние. Тогда другой поток, который ждал перехода события в свободное состояние, пробуждается и вновь становится планируемым.
  •  
    Назад к содержимому | Назад к главному меню