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

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

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

Основной процесс читает некоторую текстовую строку из стандартного ввода, и в случае, если строка начинается с буквы '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, а клиенты — сообщения с типами, равными идентификаторам их процессов.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: