Операционная система UNIX
Операционная система UNIX читать книгу онлайн
Книга посвящена семейству операционных систем UNIX и содержит информацию о принципах организации, идеологии и архитектуре, объединяющих различные версии этой операционной системы.
В книге рассматриваются: архитектура ядра UNIX (подсистемы ввода/вывода, управления памятью и процессами, а также файловая подсистема), программный интерфейс UNIX (системные вызовы и основные библиотечные функции), пользовательская среда (командный интерпретатор shell, основные команды и утилиты) и сетевая поддержка в UNIX (протоколов семейства TCP/IP, архитектура сетевой подсистемы, программные интерфейсы сокетов и TLI).
Для широкого круга пользователей.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
#include <sys/msg.h>
int msgget(key_t key, int msgflag);
Функция возвращает дескриптор объекта-очереди, либо -1 в случае ошибки. Подобно файловому дескриптору, этот идентификатор используется процессом для работы с очередью сообщений. В частности, процесс может:
□ Помещать в очередь сообщения с помощью функции msgsnd(2);
□ Получать сообщения определенного типа из очереди с помощью функции msgrcv(2);
□ Управлять сообщениями с помощью функции msgctl(2).
Перечисленные системные вызовы манипулирования сообщениями имеют следующий вид:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, const void *msgp,
size_t msgsz, int msgflg);
int msgrcv(int msqid, void *msgp,
size_t msgsz, long msgtyp, int msgflg);
Здесь
msgid
msgtyp
msgsz
long msgtype | тип сообщения |
char msgtext[] | данные сообщения |
Аргумент
msgtyp
msgtyp
msgtyp
msgtyp
msgtyp
Очереди сообщений обладают весьма полезным свойством — в одной очереди можно мультиплексировать сообщения от различных процессов. Для демультиплексирования используется атрибут
msgtype
Рассмотрим типичную ситуацию взаимодействия процессов, когда серверный процесс обменивается данными с несколькими клиентами. Свойство мультиплексирования позволяет использовать для такого обмена одну очередь сообщений. Для этого сообщениям, направляемым от любого из клиентов серверу, будем присваивать значение типа, скажем, равным 1. Если в теле сообщения клиент каким-либо образом идентифицирует себя (например, передает свой PID), то сервер сможет передать сообщение конкретному клиенту, присваивая тип сообщения равным этому идентификатору.
Поскольку функция msgrcv(2) позволяет принимать сообщения определенного типа (типов), сервер будет принимать сообщения с типом 1, а клиенты — сообщения с типами, равными идентификаторам их процессов. Схема такого взаимодействия представлена на рис. 3.19.
Рис. 3.19. Мультиплексирование сообщений в одной очереди
Атрибут
msgtype
Пример приложения "Здравствуй, Мир!", использующего сообщения:
#define MAXBUFF 80
#define PERM 0666
/* Определим структуру нашего сообщения. Она может отличаться
от структуры msgbuf, но должна содержать поле mtype. В данном
случае структура сообщения состоит из буфера обмена */
typedef struct our msgbuf {
long mtype;
char buff[MAXBUFF];
} Message;
#include <sys/ipc.h>
#include <sys/msg.h>
#include "mesg.h"
main() {
/* Структура нашего сообщения (может отличаться от
структуры msgbuf) */
Message message;
key_t key;
int msgid, length, n;
/* Получим ключ */
if ((key = ftok("server", 'A')) < 0) {
printf("Невозможно получить ключn");
exit(1);
}
/* Тип принимаемых сообщений */
message.mt_type = 1L;
/* Создадим очередь сообщений */
if ((msgid = msgget(key, РЕRМ | IPC_CREAT)) < 0) {
printf("Невозможно создать очередьn");
exit(1);
}
/* Прочитаем сообщение */
n =
msgrcv(msgid, &message, sizeof(message), message.mtype, 0);
/* Если сообщение поступило, выведем его содержимое
на терминал */
if (n > 0) {
if (write(1, message.buff, n) != n) {
printf("Ошибка выводаn");
exit(1);
}
} else {
printf("Ошибка чтения сообщенияn");
exit(1);
}
/* Удалить очередь поручим клиенту */