Семинар 9. Очереди сообщений в UNIX.

(Основывается на лекции 4 и лекции 6)

Предыдущий семинар | Программа курса | Следующий семинар

Программа семинара

  1. Сообщения как средства связи и средства синхронизации процессов.

  2. Очереди сообщений в UNIX как составная часть System V IPC.

  3. Создание очереди сообщений или доступ к уже существующей. Системный вызов msgget().

  4. Реализация примитивов send и receive. Системные вызовы msgsnd() и msgrcv().

  5. Удаление очереди сообщений из системы с помощью команды ipcrm или системного вызова msgctl().

  6. Понятие мультиплексирования. Мультиплексирование сообщений. Модель взаимодействия процессов клиент-сервер. Неравноправность клиента и сервера.

  7. Использование очередей сообщений для синхронизации работы процессов.

Цели занятия

  1. Дать понятие об очередях сообщений в UNIX.

  2. Привить навыки работы с системными вызовами msgget(), msgsnd(), msgrcv(), msgctl(),

  3. Студенты должны понять, что сообщения не обязаны быть текстовыми.

  4. Дать понятие о мультиплексировании и модели клиент-сервер.

Практические работы

  1. Прогон примера с однонаправленной передачей текстовой информации.

  2. Модификация предыдущего примера для передачи числовой информации.

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

  4. Написание, компиляция и прогон программ клиент и сервер.

План занятия

  1. Сообщения как средства связи и средства синхронизации процессов.

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

    На этом семинаре мы познакомимся с использованием очередей сообщений System V IPC для обеспечения обеих этих функций.

     

  2. Очереди сообщений в UNIX как составная часть System V IPC.

    Так как очереди сообщений входят в состав средств System V IPC, то для них верно все, что говорилось ранее об этих средствах в целом и уже знакомо нам. Очереди сообщений, как и семафоры, как и разделяемая память, являются средством связи с непрямой адресацией, требуют инициализации для организации взаимодействия процессов и специальных действий для освобождения системных ресурсов по окончании взаимодействия. Пространством имен очередей сообщений является то же самое множество значений ключа, генерируемых с помощью функции ftok(). Для выполнения примитивов send и receive соответствующим системным вызовам в качестве параметра передаются IPC дескрипторы очередей сообщений, однозначно идентифицирующих их во всей вычислительной системе.

    Очереди сообщений располагаются в адресном пространстве ядра операционной системы в виде однонаправленных списков и имеют ограничение по объему информации, хранимой в каждой очереди. Каждый элемент списка представляет собой отдельное сообщение. Сообщения имеют атрибут, называемый типом сообщения. Выборка сообщений из очереди (выполнение примитива receive) может осуществляться тремя способами:


    1. В порядке FIFO, независимо от типа сообщения.

    2. В порядке FIFO для сообщений конкретного типа.

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


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

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

     

  3. Создание очереди сообщений или доступ к уже существующей. Системный вызов msgget().

    Для создания очереди сообщений, ассоциированной с определенным ключом, или доступа по ключу к уже существующей очереди используется системный вызов msgget(), являющийся аналогом системных вызовов shmget() для разделяемой памяти и semget() для массива семафоров, который возвращает значение IPC дескриптора для этой очереди. При этом существуют те же способы создания и доступа, что и для разделяемой памяти или семафоров.
     

  4. Реализация примитивов send и receive. Системные вызовы msgsnd() и msgrcv().

    Nota bene Для выполнения примитива send служит системный вызов msgsnd(), копирующий пользовательское сообщение в очередь сообщений, заданную своим IPC дескриптором. При изучении описания этого вызова обратите особое внимание на следующие моменты:


    Nota beneПримитив receive реализуется системным вызовом msgrcv(). При изучении описания этого вызова обратите особое внимание на следующие моменты:


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

    ipcs -l

     

  5. Удаление очереди сообщений из системы с помощью команды ipcrm или системного вызова msgctl().

    После завершения процессов, использовавших очередь сообщений, она не удаляется из системы автоматически, а продолжает сохраняться в системе вместе со всеми невостребованными сообщениями до тех пор, пока не будет выполнена специальная команда или специальный системный вызов. Для удаления очереди сообщений можно воспользоваться уже знакомой нам командой ipcrm, которая в этом случае примет вид:

    ipcrm msg <IPC идентификатор>  

    Для получения IPC идентификатора очереди сообщений примените команду ipcs. Можно удалить очередь сообщений и с помощью системного вызова msgctl(). Этот вызов умеет выполнять и другие операции над очередью сообщений, но их рассмотрение лежит вне нашего курса. Если какой-либо процесс находился в состоянии ожидание при выполнении системного вызова msgrcv() или msgsnd() для удаляемой очереди, то он будет разблокирован, и системный вызов констатирует наличие ошибочной ситуации.
     
  6. Прогон примера с однонаправленной передачей текстовой информации

    Для иллюстрации всего вышесказанного давайте рассмотрим простые программы /ftp/pub/sem9/09-1a.c и /ftp/pub/sem9/stud/09-1b.c. Первая из этих программ посылает пять текстовых сообщений с типом 1 и одно сообщение нулевой длины с типом 255 второй программе. Вторая программа в цикле принимает сообщения любого типа в порядке FIFO и печатает их содержимое до тех пор, пока не получит сообщение с типом 255. Сообщение с типом 255 служит для нее сигналом к завершению работы и ликвидации очереди сообщений. Если перед запуском любой из программ очередь сообщений еще отсутствовала в системе, то программа создаст ее.

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

     

  7. Модификация предыдущего примера для передачи числовой информации.

    Nota beneВ описании системных вызовов msgsnd() и msgrcv() говорится о том, что передаваемая информации не обязательно должна представлять собой текст. Мы можем воспользоваться очередями сообщений для передачи данных любого вида. При передаче разнородной информации целесообразно информативную часть объединять внутри сообщения в отдельную структуру:

    struct mymsgbuf { long mtype;
    struct {
    short sinfo;
    float finfo;
    } info;
    } mybuf;

    для правильного вычисления длины информативной части. В некоторых вычислительных системах числовые данные размещаются в памяти с выравниванием на определенные адреса (например, на адреса кратные 4). Поэтому реальный размер памяти, необходимой для размещения нескольких числовых данных, может оказаться больше суммы длин этих данных, т. е. в нашем случае, вообще говоря, sizeof(info)>=sizeof(short)+sizeof(float). Для полной передачи информативной части сообщения в качестве длины нужно указывать не сумму длин полей, а полную длину структуры. Модифицируйте предыдущие программы для передачи нетекстовых сообщений.
     

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

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

  9. Понятие мультиплексирования. Мультиплексирование сообщений. Модель взаимодействия процессов клиент-сервер. Неравноправность клиента и сервера.

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


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

  10. Написание, компиляция и прогон программ клиент и сервер.

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

  11. Использование очередей сообщений для синхронизации работы процессов.

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

      Задача повышенной сложности: реализуйте семафоры через очереди сообщений.


Предыдущий семинар | Программа курса | Следующий семинар