Учебная деятельность    

Операционные системы

Самостоятельная работа №3

Исследование метода взаимодействия процессов с помощью очередей сообщений

Цель работы: изучение методов взаимодействия процессов с помощью очередей сообщений.

Общие сведения

Обмен сообщениями между процессами на основе буфера обладает рядом недостатков, а именно:

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

В качестве последних выступают очередь процессов, пославших сообщение, и очередь процессов, ждущих сообщение.

Дадим словесное описание методов записи и чтения сообщения, а затем опишем данное средство обмена сообщениями как объект операционной среды.

Запись сообщения включает в себя следующие действия:

Чтение сообщения включает в себя следующие действия:

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

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

           Процесс 1                             Процесс 2
       ┌──────┴──────┐                              │
       │    запись   │                              │
       └──────┬──────┘                              │
              │ожидание                             │
       ┌──────┴──────┐                      ┌───────┴───────┐
       │возобновление│                      │     чтение    │
       └──────┬──────┘----------------------└───────┬───────┘
     Рис.1. Процесс 1 подошел к примитиву записи раньше, чем процесс 2 подошел к примитиву чтения.
           Процесс 2                             Процесс 2
              │                              ┌──────┴──────┐
              │                              │начало чтения│
              │                              └──────┬──────┘
              │                                     │ожидание
      ┌───────┴───────┐                      ┌──────┴──────┐
      │    запись     │                      │конец  чтения│
      └───────┬───────┘----------------------└──────┬──────┘
     Рис.2. Процесс 1 подошел к примитиву записи позже,  чем процесс 2 подошел к примитиву чтения.

Средство обмена сообщениями, удовлетворяющее приведенному выше описанию, может быть предствлено следующим образом:

ТPostBox = Object
    MessageList  : TMessageList;{очередь указателей на сообщения}
    SendProcList : TList;{очередь процессов, пославших сообщения}
    WaitProcList : TList;  {очередь процессов. ждущих сообщение}
    Constructor Init;
    Destructor  Done; Virtual;
    Procedure   PutMsg(M : Pointer); {послать сообщение}
    Function    GetMsg   : Pointer;  {принять сообщение}
End {TPostBox}.

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

Constructor TPostBox.Init;
Begin
     MessageList.Init;
     SendProcList.Init;
     WaitProcList.Init;
End {TPostBox.Init};
Destructor TPostBox.Done;
Begin
     MessageList.Done;
     SendProcList.Done;
     WaitProcList.Done;
End {TPostBox.Done};
Procedure TPostBox.PutMsg(M : Pointer);
Var
     Предыдущий : Процесс;
Begin
     Запретить_прерывания;
     MessageList.Insert(M);
     Предыдущий :=  Текущий;
     SendProcList.Insert(Предыдущий);
     If WaitProcList.Первый <> NIL Then Begin
        Текущий := WaitProcList.Первый;
        WaitProcList.Remove(Текущий);
     End Else Begin
        Текущий := ReadyList.Первый;
        ReadyList.Remove(Текущий);
     End {If};
     Передать_управление(Предыдущий, Текущий);
     Разрешить_прерывания;
End  {TPostBox.PutMsg};
Function TPostBox.GetMsg : Pointer;
Var
     M          : Pointer;
     S          : Процесс;
     Предыдущий : Процесс;
Begin
     Запретить_прерывания;
     If MessageList.Первый = NIL Then Begin
        Предыдущий := Текущий;
        WaitProcList.Insert(Предыдущий);
        Текущий := ReadyList.Первый;
        ReadyList.Remove(Текущий);
        Передать_управление(Предыдущий, Текущий);
        Запретить_прерывания;
     End {If};
     M := MessageList.Первый;
     MessageList.Remove(M);
     GetMsg := M;
     S := SendProcList.Первый;
     SendProcList.Remove(S);
     ReadyList.Insert(S);
     Разрешить_прерывания;
End {TPostBox.GetMsg}.

Представленный объект лишь моделирует в среде MS DOS работу очередей сообщений, реализованных в современных операционных системах, однако дает представление о путях решения задачи синхронизации записи и чтения сообщений разными процессами.

Задание

  1. Реализовать объект TPostBox средствами языка Pascal.
  2. Прокомментировать каждую строчку объекта TPostBox.
  3. Написать демонстрационную программу, иллюстрирующую функционирование объекта TPostBox.