Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
os3.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
683.52 Кб
Скачать

3.10. Примитивы ядра для обмена сообщениями

Напомню, что мы классифицировали примитивы ядра на три группы:

  1. примитивы управления процессами;

  2. примитивы синхронизации процессов;

  3. примитивы обмена данными.

Синхронизация и обмен данными вместе называются обобщенно взаимодействием.

Если опять построить некоторую многоуровневую классификацию, то примитивы второго и третьего класса следует поместить в следующую иерархическую схему:

Вопрос (

Обмен данными

─────────────

Синхронизация

)Вопрос

Т.е. обмен данными - это логически более высокий уровень взаимодействия процессов, чем синхронизация.

Обмен данными не может быть реализован без синхронизации.

При этом средства синхронизации «встраиваются» в средства обмена данными таким образом, что они оказываются скрытыми от пользователя.

Пользователю предоставляется пара примитивов типа: SEND, RECEIVE или READ, WRITE.

Обмен данными может рассматриваться в двух аспектах.

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

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

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

Как и ранее, мы рассмотрим модели обмена данными, а затем приведем примеры средств обмена данными в реальных операционных средах. Базовым средством обмена данными между процессами является средство, называемое буфером.

3.10.1. Буфер как средство коммуникации между процессами

При организации связи между процессами с помощью любого средства требуется составить спецификацию к этому средству.

Вопрос (

Спецификация буфера как средства связи выглядит следующим образом:

  1. сообщения в буфере имеют фиксированный размер;

  2. размер буфера ограничен, буфер - кольцевой;

  3. посылка сообщения в полный буфер недопустима;

  4. чтение сообщения из пустого буфера также недопустима.

)Вопрос

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

Вопрос (

Type

PBuffer = ^TBuffer;

TBuffer = Object

N : [0..N]; {текущее количество сообщений в буфере}

in : [0..N-1]; {индекс ячейки, в которую производится текущая запись}

out : [0..N-1]; {индекс ячейки, из которой производится текущее чтение}

Buf : Array[0..N-1] Of TMessage;

RList : PList; {очередь процессов, ждущих чтения}

WList : PList; {очередь процессов, ждущих записи}

Constructor Init;

Destructor Done;

Procedure Write(M : TMessage);

Procedure Read(Var M : TMessage);

End {TBuffer};

)Вопрос

Схема использования буфера выглядит следующим образом.

Var

B : PBuffer;

Begin

B := New(PBuffer, Init);

...

Dispose(B, Done);

End.

Процесс 1: Процесс 2:

Procedure Производитель; Procedure Потребитель;

Var Var

Message : TMessage; Message : TMessage;

Begin Begin

While True Do Begin While True Do Begin

... ...

Сформировать(Message); B^.Read(Message);

B^.Write(Message); Обработать(Message);

... ...

End {While}; End {While};

End {Производитель}; End {Потребитель};

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

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

Вопрос (

)Вопрос

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

Вопрос (

)Вопрос

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

Распишем теперь методы монитора БУФЕР.

Constructor TBuffer.Init;

Begin

N := 0;

in := 0;

out := 0;

RList := New(PList, Init);

WList := New(PList, Init);

End {TBuffer.Init};

Destructor TBuffer.Done;

Begin

Dispose(RList, Done);

Dispose(WList, Done);

End {TBuffer.Done};

Вопрос (

Procedure TBuffer.Write(M : TMessage);

Begin

Запрет прерываний;

If n = N Then Begin {буфер полон}

WList^.Insert(Текущий процесс); {ждем записи}

ПЕРЕНАЗНАЧИТЬ ПРОЦЕССОР;

End {If};

Inc(n);

Buf[in] := M;

in := (in + 1) MOD N;

If RList не пустая Then Begin {активизация ждущего чтения}

Очередь_готовых.Insert(Текущий процесс);

RList^.Remove(Первый процесс);

Передать управление(Текущий процесс, Первый процесс);

End {If};

Разрешение прерываний;

End {TBuffer.Write};

)Вопрос

Вопрос (

Procedure TBuffer.Read(Var M : TMessage);

Begin

Запрещение прерываний;

If n = 0 Then Begin

RList^.Insert(Текущий процесс); {ждем чтения}

ПЕРЕНАЗНАЧИТЬ ПРОЦЕССОР;

End {If};

Dec(n);

M := Buf[out];

out := (out + 1) MOD N;

If WList не пустая Then Begin {активизация ждущего записи}

Очередь_готовых.Insert(Текущий процесс);

WList^.Remove(Первый процесс);

Передать управление(Текущий процесс, Первый процесс);

End {If};

Разрешение прерываний;

End {TBuffer.Read};

)Вопрос

Выводы

  1. Внешне работа с буфером напоминает работу с файлом: Создать; Записать; Прочитать; Разрушить; Работа любых средств обмена данными похожа на эти действия.

  1. Две очереди процессов используются в качестве средств синхронизации записи и чтения. Вместо прямого использования очередей могут использоваться семафоры. В этом случае нужна пара семафоров, которые имеют смысл «НЕ_ПУСТ» и «НЕ_ПОЛОН». Когда процесс пишет сообщение в буфер, а он оказывается полным, процесс выполняет операцию НЕ_ПОЛОН.Р. Если буфер не полон и операция записи прошла успешно, то процесс выполняет операцию НЕ_ПУСТ.V, активизируя читающий процесс, ждущий записи. Когда процесс читает сообщение из буфера, а он оказывается пустым, процесс выполняет операцию НЕ_ПУСТ.Р. Если буфер не пуст и операция чтения прошла успешно, то процесс выполняет операцию НЕ_ПОЛОН_V, активизируя пишущий процесс, ждущий чтения.

Вопрос (

  1. Недостатками буфера являются: 1) фиксированный размер буфера; 2) реальная перезапись данных в буфер и из буфера.

)Вопрос

Следующий метод обмена данными устраняет недостатки буфера.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]