Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛР5.docx
Скачиваний:
15
Добавлен:
12.02.2016
Размер:
400.53 Кб
Скачать

Черги повідомлень

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

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

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

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

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

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

#include <sys / ipc.h>

#include <sys / msg.h>

По системному виклику msgget у відповідь на ключ (key), що визначає унікальне ім'я

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

int msgqid = msgget(key_t key, int flag)

Таким чином, черга повідомлення володіє живучістю ядра. Для поміщення повідомлення в чергу служить системний виклик msgsnd.

int rnsgsnd (int msgqid, void *rnsg, size_t size, int flaq)

де msg - це покажчик на структуру довжиною size, що містить визначений користувачем цілочисельний тип повідомлення і символьний масив-повідомлення, причому розмір користувальницьких даних обчислюється таким чином: size = sizeof (msg) - sizeof (long).

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

struct rnsq {

lonq mtype; / * Тип повідомлення * /

char mtext [SOMEVALUE]; / * текст повідомлення * /

};

Поле типу long завжди повинно бути першим у структурі, далі можуть слідувати в довільному порядку дані користувача, в цьому випадку ядро не накладає обмеження на тип даних, а тільки на їх довжину (залежну від реалізації системи). Параметр flag визначає дії ядра для потоку, що здійснив виклик при читанні черги чи виходу за межі допустимих розмірів внутрішньої буферної пам'яті. Якщо flag = 0, то за відсутності повідомлення в черзі потік блокується.

Якщо flag = IPCNOWAIT, то потік не блокується і при відсутності повідомлення повертається помилка ENOMSG.

Умовами успішної постановки повідомлення в чергу є

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

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

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

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

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

int rnsgrcv (int msgqid, void * msg, size_t size, long rnsg_type, int flag)

Аргумент rnsg_type задає тип повідомлення, яке потрібно зчитати з черги

  • якщо значення дорівнює 0, то повертається перше повідомлення в черзі, тобто найстарше повідомлення;

  • якщо тип більше 0, то повертається перше повідомлення, тип якого дорівнює зазначеному числу;

  • якщо тип менший нуля, повертається перше повідомлення з найменшим типом, значення якого менше, або рівне модулю вказаного числа.

Значення size в даному випадку вказує ядру, що дані, які повертаються не повинні перевищувати розміру зазначеного в size.

Системний виклик msgctl дозволяє управляти чергами повідомлень

int msgctl (int msgqid, int comm and, struct msgid_ds * msg_stat)

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

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

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

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

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