Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Метвказівки для Астистовой1.doc
Скачиваний:
2
Добавлен:
08.11.2019
Размер:
288.26 Кб
Скачать

Лабораторна робота № 6

Тема: Повідомлення як засіб міжпроцесної взаємодії.

Мета роботи : навчитися організовувати обмін даними між процесами з використанням повідомлень.

Основні положення.

Як зазначалося вище (лабораторна робота № 5), одним із засобів взаємодії процесів є повідомлення. Особливість цього методу полягає в тому, що він не ґрунтується на спільно використовуваних даних. Засоби передавання повідомлень ґрунтуються на обміні повідомленнями – фрагментами даних змінної довжини.

Для таких об'єктів IPC, як черги повідомлень, процес призначення імен є більш складним, ніж просто вказівка імені файлу. Ім'я для цих об'єктів називається ключем і генерується функцією ftok( ) із двох компонентів – імені файлу і відмінного від нуля ідентифікатора проекту.

В якості імені файлу можна використовувати маршрутне ім'я деякого файлу, яке відоме взаємодіючим процесам. Наприклад, це може бути ім'я програми-сервера. Важливо, щоб цей файл існував на момент створення ключа. Небажано використовувати ім'я файлу, який створюється і видаляється в процесі роботи додатку, оскільки при генерації ключа використовується номер індексного дескриптора файлу.

Вказаний засіб IPC має свій унікальний ідентифікатор, який використовується ядром ОС для роботи з об'єктом. Будь-яка черга повідомлень може мати той же числовий ідентифікатор, що і розділювана пам'ять, але будь-які дві черги повідомлень повинні мати різні ідентифікатори.

Черга повідомлень зберігається у вигляді внутрішнього однонаправленого зв'язаного списку в адресному просторі ядра. Для кожної черги ядро створює заголовок черги (msgid), де міститься інформація про права доступу до черги (msgperm), її поточний стан, а також вказівники на перше і останнє повідомлення, що зберігаються у вигляді зв'язаного списку.

1. Черга повідомлень.

Для забезпечення можливості обміну повідомленнями між процесами механізм черг підтримується наступними системними викликами:

  • msgget() для створення нової черги повідомлень чи отримання дескриптора існуючої черги;

  • msgsnd() для розміщення повідомлення у вказану чергу повідомлень;

  • msgrcv() для вибірки повідомлення із черги повідомлень;

  • msgctl() для виконання ряду керуючих дій.

Прототипи перерахованих системних викликів описані у файлах

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

int msgsnd(int msgid, struct msgbuf *msgp, int msgsz, int msgflg);

int msgrcv(int msgid, struct msgbuf *msgp, int msgsz, long msgtyp, int msgflg).

Тут msgid є дескриптором об'єкту, отриманого в результаті виклику msgget() у відповідь на ключ key і набір прапорців; при цьому ядро або створює нову чергу повідомлень і повертає користувачу ідентифікатор створеної черги, або знаходить елемент таблиці черг повідомлень, що містить вказаний ключ, і повертає відповідний ідентифікатор черги.

int msgqid = msgget(key_t key, int msgflg).

Для розміщення повідомлення в чергу використовується системний виклик msgsnd():

int msgsnd(int msgid, struct msgbuf *msgp, int msgsz, int msgflg);

де msg – це вказівник на структуру довжиною sz, що містить визначений користувачем цілий тип повідомлення і символьний масив-повідомлення.

Структура msg має вигляд:

struct msg {

long mtype; /* тип повідомлення */

char mtext[SOMEVALUE]; /* текст повідомлення (SOMEVALUE – будь-яке */};

Параметр flag визначає дії ядра при виході за межі допустимих розмірів внутрішньої буферної пам'яті.

Умовами успішного розміщення повідомлення в чергу є:

  • наявність у процесу прав на запис в дану чергу повідомлень;

  • не перевищення довжиною повідомлення заданої системою верхньої межі;

  • додатнє значення вказаного у повідомленні типу повідомлення.

Якщо ж виявиться, що нове повідомлення неможливо буферизувати в ядрі по причині перевищення верхньої межі сумарної довжини повідомлень, що знаходяться в даній черзі повідомлень (при цьому прапорець IPC_NOWAIT відсутній), то процес, який звернувся, відкладається («присипляється») до того часу, поки черга повідомлень не розвантажиться процесами, які чекають отримання повідомлень.

Для прийому повідомлень використовується системний виклик msgrcv():

int msgrcv(int msgid, struct msgbuf *msgp, int msgsz, long msgtyp, int msgflg).

Системний виклик msgctl()

int msgctl (int msgqid, int command, struct msqid_ds *msg_stat)

використовується

  • для опитування стану описувача черги повідомлень (command = IPC_STAT) і розміщення його в структуру msg_stat;

  • для зміни його стану (command = IPC_SET), наприклад, зміни прав доступу до черги;

  • для знищення вказаної черги повідомлень (command = IPC_RMID).