Управление очередью сообщений. — КиберПедия 

История создания датчика движения: Первый прибор для обнаружения движения был изобретен немецким физиком Генрихом Герцем...

Семя – орган полового размножения и расселения растений: наружи у семян имеется плотный покров – кожура...

Управление очередью сообщений.

2017-11-18 351
Управление очередью сообщений. 0.00 из 5.00 0 оценок
Заказать работу

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

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

int msgctl(int msqid, int cmd, struct msgid_ds *buf)

Данный вызов используется для получения или изменения процессом управляющих параметров, связанных с очередью и уничтожения очереди. Ее аргументы — идентификатор ресурса, команда, которую необходимо выполнить, и структура, описывающая управляющие параметры очереди. Тип msgid_ds описан в заголовочном файле <sys/message.h>, и представляет собой структуру, в полях которой хранятся права доступа к очереди, статистика обращений к очереди, ее размер и т.п.

Возможные значения аргумента cmd:

IPC_STAT – скопировать структуру, описывающую управляющие параметры очереди по адресу, указанному в параметре buf

IPC_SET – заменить структуру, описывающую управляющие параметры очереди, на структуру, находящуюся по адресу, указанному в параметре buf

IPC_RMID – удалить очередь. Как уже говорилось, удалить очередь может только процесс, у которого эффективный идентификатор пользователя совпадает с владельцем или создателем очереди, либо процесс с правами привилегированного пользователя.

XI. Использование очереди сообщений.

Пример программы, где основной процесс читает некоторую текстовую строку из стандартного ввода, и в случае, если строка начинается с буквы 'a', эта строка в качестве сообщения будет передана процессу А, если 'b' - процессу В, если 'q' - то процессам А и В, затем будет осуществлен выход. Процессы А и В распечатывают полученные строки на стандартный вывод.

Основной процесс.

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#include <string.h>

#include <unistd.h>

#include <stdio.h>

 

struct {

long mtype; /* тип сообщения */

char Data[256]; /* сообщение */

} Message;

 

int main(int argc, char **argv)

{

key_t key; int msgid; char str[256];

 

key = ftok("/usr/mash",'s');

/*получаем уникальный ключ, однозначно определяющий доступ к ресурсу */

msgid=msgget(key, 0666 | IPC_CREAT);

/*создаем очередь сообщений, 0666 определяет права доступа */

 

for(;;) {

/* запускаем вечный цикл */

gets(str); /* читаем из стандартного ввода строку */

strcpy(Message.Data, str);

/* и копируем ее в буфер сообщения */

switch(str[0]){

case 'a':

case 'A':

Message.mtype = 1;

/* устанавливаем тип */

msgsnd(msgid, (struct msgbuf*) (&Message), strlen(str) + 1, 0);

/* посылаем сообщение в очередь */

break;

case 'b':

case 'B':

Message.mtype = 2;

msgsnd(msgid, (struct msgbuf*) (&Message), strlen(str) + 1, 0);

break;

case 'q':

case 'Q':

Message.mtype = 1;

msgsnd(msgid, (struct msgbuf*) (&Message), strlen(str) + 1, 0);

Message.mtype = 2;

msgsnd(msgid, (struct msgbuf*) (&Message), strlen(str) + 1, 0);

sleep(10);

/* ждем получения сообщений процессами А и В */

msgctl(msgid, IPC_RMID, NULL);

/* уничтожаем очередь*/

return 0;

default:

break;

}

}

}

Процесс-приемник А

/* процесс В аналогичен с точностью до четвертого параметра в msgrcv */

 

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#include <stdio.h>

 

struct {

long mtype;

char Data[256];

} Message;

 

int main(int argc, char **argv)

{

key_t key; int msgid;

 

key = ftok("/usr/mash",'s');

/* получаем ключ по тем же параметрам */

msgid = msgget(key, 0666 | IPC_CREAT);

/*подключаемся к очереди сообщений */

for(;;) {

/* запускаем вечный цикл */

msgrcv(msgid, (struct msgbuf*) (&Message), 256, 1, 0);

/* читаем сообщение с типом 1*/

if (Message.Data[0]=='q' || Message.Data[0]=='Q') break;

printf("\nПроцесс-приемник А: %s", Message.Data);

}

return 0;

}

 

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

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

XII. Очередь сообщений. Модель «клиент-сервер»

Server

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#include <string.h>

 

int main(int argc, char **argv)

{

struct {

long mestype;

char mes [100];

} messageto;

struct {

long mestype;

long mes;

} messagefrom;

 

key_t key;

int mesid;

 

key = ftok("example",'r');

mesid = msgget (key, 0666 | IPC_CREAT);

 

while(1)

{

if (msgrcv(mesid, &messagefrom, sizeof(messagefrom), 1, 0) <= 0) continue;

messageto.mestype = messagefrom.mes;

strcpy(messageto.mes, "Message for client");

msgsnd (mesid, &messageto, sizeof(messageto), 0);

}

msgctl (mesid, IPC_RMID, 0);

return 0;

}

Client

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#include <unistd.h>

#include <stdio.h>

 

int main(int argc, char **argv)

{

struct {

long mestype; /*описание структуры сообщения*/

long mes;

} messageto;

struct {

long mestype; /*описание структуры сообшения*/

char mes[100];

} messagefrom;

key_t key;

int mesid;

long pid = getpid();

key = ftok("example", 'r');

mesid = msgget(key, 0); /*присоединение к очереди сообщений*/

messageto.mestype = 1;

messageto.mes = pid;

msgsnd (mesid, &messageto, sizeof(messageto), 0); /* отправка */

while (msgrcv (mesid, &messagefrom, sizeof(messagefrom), pid, 0) <= 0);

/*прием сообщения */

 

printf("%s\n", messagefrom.mes);

return 0;

}

БИЛЕТ 41

Разделяемая память

 

Рис. 11 Разделяемая память

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

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

Рассмотрим набор системных вызовов для работы с разделяемой памятью.

Создание общей памяти.

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

int shmget (key_t key, int size, int shmemflg)

Аргументы этого вызова: key - ключ для доступа к разделяемой памяти; size задает размер области памяти, к которой процесс желает получить доступ. Если в результате вызова shmget() будет создана новая область разделяемой памяти, то ее размер будет соответствовать значению size. Если же процесс подключается к существующей области разделяемой памяти, то значение size должно быть не более ее размера, иначе вызов вернет –1. Заметим, что если процесс при подключении к существующей области разделяемой памяти указал в аргументе size значение, меньшее ее фактического размера, то впоследствии он сможет получить доступ только к первым size байтам этой области.

Отметим, что в заголовочном файле <sys/shm.h> определены константы SHMMIN и SHMMAX, задающий минимально возможный и максимально возможный размер области разделяемой памяти. Если процесс пытается создать область разделяемой памяти, размер которой не удовлетворяет этим границам, системный вызов shmget() окончится неудачей.

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

В случае успешного завершения вызов возвращает положительное число – дескриптор области памяти, в случае неудачи - -1.


Поделиться с друзьями:

Индивидуальные и групповые автопоилки: для животных. Схемы и конструкции...

Механическое удерживание земляных масс: Механическое удерживание земляных масс на склоне обеспечивают контрфорсными сооружениями различных конструкций...

Особенности сооружения опор в сложных условиях: Сооружение ВЛ в районах с суровыми климатическими и тяжелыми геологическими условиями...

Эмиссия газов от очистных сооружений канализации: В последние годы внимание мирового сообщества сосредоточено на экологических проблемах...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.025 с.