Параллельное программирование: Учебное пособие, страница 42

Если i-тый процесс-поставщик подготовил порцию данных в количестве ni единиц и желает их записать в буфер, то сначала выполнится проверка: не заблокирован ли буфер для записи и есть ли в нем свободное место для размещения ni единиц данных? Если проверка не дает запрета на запись в буфер, то она производится в этом же критическом интервале, иначе буфер блокируется (bb:=1). Объем порции, предназначенной для размещения в буфере, запоминается в собственной ячейке  wish[i], i-тый процесс ставится в режим ожидания, открывая свой семафор P(смф[i]) для свободного доступа к сохраненной порции данных процессами-потребителями. Общий семафор P(job) получает значение, которое дает возможность войти в критическую область другим процессам, а операцией V(n) оповещаются другие процессы о наличии порций в буфере.


Рисунок 2.23.

Правая часть алгоритма на рисунке 2.23 описывает поведение j-того потребителя данных, который входит в критическую секцию для взятия из буфера порций данных, оставленных процессом i . Если блокировки буфера не было, то порция немедленно изымается. Если же буфер был заблокирован, то производится поиск номера процесса, поместившего в буфер максимальную порцию данных. По параметрам этого процесса увеличивается число свободных мест в буфере ( k := k – max ), удовлетворяется желание производителя с индексом imax поместить свою порцию данных в буфер (wish[max]:=0) и изменением значения его семафора ( V(смф[imax]) ) позволяется imax-у процессу продолжить работу. После таких разрешительных акций для одного из производителей управление опять передается оператору проверки блокировки буфера, чтобы выяснить, нельзя ли запустить и других приостановленных производителей. Процесс выяснения закончится либо разблокированием буфера, либо недостатком свободного места в буфере для размещения предложенной максимальной порции информации. После запуска соответствующих производителей, критический интервал потребителя завершается.

Подводя итог разбору методов охранения критических интервалов от одновременного обращения нескольких процессов к разделяемым переменным или областям данных, можно заметить большую логическую сложность программных фрагментов при их программировании в системе машинных команд и серьезную зависимость логики действия от конкретных требований по работе с разделяемыми данными. Логическая сложность делает программы плохо структурируемыми, аналогично программам с неумеренным применением операторов перехода goto. Это вынуждает применять операции над семафорами в произвольных местах программы, а не размещать их вблизи исполненной операции. И, второе, применение P-операции к одному семафору, а V-операции к другому приводит к затруднительному обнаружению факта нарушения критических интервалов.

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

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