Сдам Сам

ПОЛЕЗНОЕ


КАТЕГОРИИ







Парадигма (шаблон) взаимодействия процессов: производитель – потребитель





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

При реализации данной парадигмы возможны схемы с неограниченным и ограниченным буфером, используемым для связи двух процессов.

 
Схема с неограниченным буфером (unbounded buffer) подразумевает, что на размер используемого буфера теоретически нет ограничений.
 
Схема с ограниченным буфером (bounded buffer) предполагается определенное ограничение размера буфера, например, константой BUFFER_SIZE.

При реализации следует учесть, что схема с ограниченным буфером, с точки зрения принципов надежных и безопасных вычислений (trustworthy computing, см. "Понятие операционной системы (ОС), цели ее работы. Классификация компьютерных систем"), представляет опасность атаки "переполнение буфера"(buffer overrun) – ошибочного или преднамеренного превышения размера буфера. Чтобы избежать этой уязвимости, при заполнении буфера необходимо проверять его размер.

Реализуем ограниченный буфер следующим образом. Информация хранится в массиве с двумя указателями: in - для считывания и использования очередного элемента информации процессом-потребителем и out - для записи очередного сгенерированного элемента информации процессом-производителем. При считывании из буфера очередной элемент удаляется, и указатель in, соответственно, продвигается. При записи в буфер продвигается указатель out. Для удобства будем считать буфер циклическим, т.е. при его заполнении следующим заполняемым элементом будет нулевой (если он освободился), следующим после него – первый и т.д. Таким образом, процесс-производитель должен вычислять индекс в буфере, по которому он записывает следующий элемент, по формуле (out + 1) % BUFFER_SIZE, где "%" операция взятия остатка от деления. Аналогично, процесс-потребитель должен вычислять индекс следующего элемента информации в буфере по формуле (in + 1) % BUFFER_SIZE. Учтем также две возможных ситуации: переполнение буфера (при генерации производителем числа элементов, большего длины буфера) и исчерпание буфера (в случае, если потребитель взял из буфера последний на данный момент сгенерированный элемент). Чтобы избежать обращения за границы буфера, при переполнении буфера производитель должен будет ждать, пока в буфере не освободится хотя бы один элемент, а при исчерпании буфера должен будет ждать потребитель, пока хотя бы один новый элемент не появится в буфере.

Реализация представления буфера на языке Си может иметь вид:

#define BUFFER_SIZE 1000 /* или другое конкретное значение */ typedef struct {

...

} item;

item buffer[BUFFER_SIZE]; int in = 0; int out = 0;

Реализация схемы алгоритма процесса-производителя имеет вид:

item nextProduced; /* следующий генерируемый элемент */

while (1) { /* бесконечный цикл */ while (((in + 1) % BUFFER_SIZE) == out); /* ждать, пока буфер переполнен */ buffer[in] = nextProduced; /* генерация элемента */

in = (in + 1) % BUFFER_SIZE; }

Соответственно, реализация процесса-потребителя будет иметь вид:

item nextConsumed; /* следующий используемый элемент */ while (1) { /* бесконечный цикл */ while (in == out)

; /* ждать, пока буфер пуст */

nextConsumed = buffer[out]; /* использование элемента */

out = (out + 1) % BUFFER_SIZE; }

Данный код может быть использован как шаблон (pattern) для реализации схемы производитель – потребитель в любой системе.

Коммуникация процессов

Рассмотрим теперь возможные механизмы для непосредственной коммуникации процессов и синхронизации их действий.

Наиболее распространенный их них - система сообщений; при этом процессы взаимодействуют между собой без обращений к общим переменным.

Средства коммуникации между процессами обеспечивают две операции вида:

 
send (message) – отправка сообщения message; размер сообщения может быть постоянным или переменным;

 
receive (message) – получение сообщения в буфер message.

Если процессам P и Q требуется взаимодействовать между собой, им необходимо:

- Установить связь (communication link) друг с другом

- Обменяться сообщениями вида send/receive.

Реализация связи может быть физической (общая память, аппаратная шина) или логической (например, логические свойства).







Что делать, если нет взаимности? А теперь спустимся с небес на землю. Приземлились? Продолжаем разговор...

Живите по правилу: МАЛО ЛИ ЧТО НА СВЕТЕ СУЩЕСТВУЕТ? Я неслучайно подчеркиваю, что место в голове ограничено, а информации вокруг много, и что ваше право...

Что способствует осуществлению желаний? Стопроцентная, непоколебимая уверенность в своем...

Конфликты в семейной жизни. Как это изменить? Редкий брак и взаимоотношения существуют без конфликтов и напряженности. Через это проходят все...





Не нашли то, что искали? Воспользуйтесь поиском гугл на сайте:


©2015- 2024 zdamsam.ru Размещенные материалы защищены законодательством РФ.