Конвейеры и очереди сообщений
Конвейер(pipe - программный канал)является средством, с помощью которого можно производить обмен данными между процессами. Принцип работы конвейера основан на механизме ввода/вывода, который используется для работы с файлами в UNIX, то есть задача, передающая информацию, действует так, как будто она записывает данные в файл, а задача, для которой предназначается эта информация, читает ее из этого файла. Операции записи и чтения осуществляются не записями, как это делается в обычных файлах, а потоком байтов, как это было принято в UNIX-системах.
Конвейеры представляют собой буферную память, работающую по принципу FIFO, то есть по принципу обычной очереди. Максимальный размер конвейера - 64 Кбайт, т.к. в 16-разрядных мини-ЭВМ, для которых создавалась эта система, нельзя было создать массив данных большего размера.
Функционирование конвейера представляет собой реализацию очереди на массивах. Имеются указатели начала (head) и конца очереди (tail), которые циклически перемещаются по массиву. В начальный момент оба указателя равны нулю. Добавление самого первого элемента в пустую очередь приводит к тому, что указатели head и tail принимают значение, равное 1 (в массиве появляется первый элемент). Добавление нового элемента изменяет значение второго указателя. Чтение (и удаление) элемента (читается и удаляется всегда первый элемент очереди) приводит к модификации значения указателя head. В результате операций записи и чтения элементов в массиве, моделирующем очередь элементов, указатели перемещаются от начала массива к концу. При достижении указателем значения индекса последнего элемента массива значение указателя вновь становится единичным (если при этом не произошло переполнение массива, то есть количество элементов в очереди не стало больше числа элементов в массиве). Таким образом, массив замыкается в кольцо, организуя круговое перемещение указателей head и tail, которые отслеживают первый и последний элементы в очереди.
Основными системными запросами для работы с конвейером (на примере API OS/2) являются: функция создания конвейера (DosCreatePipe); функция чтения из конвейера (DosRead); функция записи в конвейер (DosWrite).
Очереди сообщений(Queue) являются более сложным методом связи между взаимодействующими процессами по сравнению с каналами. С помощью очередей можно из одной или нескольких задач независимым образом посылать сообщения некоторой задаче-приемнику. При этом только процесс-приемник может читать и удалять сообщения из очереди, а процессы-клиенты имеют право только помещать в очередь свои сообщения. Очередь работает только в одном направлении. Если необходима двухсторонняя связь, то нужно создать две очереди.
Работа с очередями имеет следующие отличия от работы с конвейерами.
1 Очереди сообщений, в отличие от конвейеров, предоставляют возможность использовать несколько дисциплин обработки сообщений:
- FIFO - сообщение, записанное первым, будет первым и прочитано;
- LIFO - сообщение, записанное последним, будет прочитано первым;
- приоритетный - сообщения читаются с учетом их приоритетов;
- произвольный доступ, то есть можно читать любое сообщение.
2 При чтении сообщения из конвейера оно удаляется из него, в очереди этого не происходит, и сообщение можно прочитать несколько раз.
3 В очередях хранятся не сами сообщения, а только их адреса в памяти и размер. Эта информация размещается системой в сегменте памяти, доступном для всех задач, общающихся с помощью данной очереди.
При чтении из очереди задача-приемник должна знать идентификатор процесса (PID - process ID), который передал сообщение; адрес и длину переданного сообщения; ждать или нет, если очередь пуста; приоритет переданного сообщения; номер освобождаемого семафора, когда сообщение передается в очередь.
Управление работой очереди производится с помощью следующих основных функций: создание новой очереди (CreateQueue); открытие существующей очереди(OpenQueue); чтение и удаление сообщения из очереди (ReadQueue); чтение сообщения без его последующего удаления из очереди (PeekQueue); добавление сообщения в очередь (WriteQueue); завершение использования очереди (CloseQueue); удаление из очереди всех сообщений (PurgeQueue); определение числа элементов в очереди (QueryQueue).
Дата добавления: 2017-11-04; просмотров: 748;