Чтение онлайн

ЖАНРЫ

QNX/UNIX: Анатомия параллелизма
Шрифт:

struct IdLabel_t { // Структура, содержащая,

int id; // -.инвентаризационную метку процесса

char name[PROC_NAME_MAX]; // - инвентаризационное имя процесса

} IdLabel[] = {

/* диапазон выделенный Группе # 1: от 0x5000 до 0x50ff */

0x5001, "пробный менеджер ресурсов",

0x5002, "первый тестовый клиент для менеджера ресурсов",

0x5003, "второй тестовый клиент для менеджера ресурсов",

0x5004, "третий
тестовый клиент для менеджера ресурсов",

0x50ff, "четвертый тестовый клиент для менеджера ресурсов"

/* диапазон, выделенный Группе # 2: от 0x5100 до 0x51ff */

/* диапазон, выделенный Группе # 3: от 0x5200 до 0x52ff */

};

char Anonymous[] = "чуждый процесс";

int ALLNUM_MYPROC = sizeof(IdLabel) /

sizeof(IdLabel[0]);

Код процесса-клиента

Как было сказано, клиент открывает файл (функция

open
), после чего использует
MsgSend
, отсылая сообщения и получая ответы.

#include <stdio.h>

#include <stdlib.h>

#include <fcntl.h>

#include <sys/neutrino.h>

#include <sys/iomsg.h>

#include <locale.h>

#include <string.h>

#include "/home/ZZZ/TESTS/MR/MessTest.h"

int main {

int fdRM; // Дескриптор соединения с менеджером ресурсов

char BufferSend[MESSIZE_MAX], BufferReply[MESSIZE_MAX];

setlocale(LC_CTYPE, "C-TRADITIONAL");

if (fdRM = open(strcat(strcpy(BufferSend, NET_REG),

"/dev/MESSTEST/RM"), O_RDWR)) == -1)) {

printf("Клиент не нашел имени менеджера!\n");

fflush(stdout);

return(-1);

}

/* Заполнение заголовка - первых 4-х байт сообщения, содержащего

инвентаризационную метку данного процесса (описаны в "IRL32.h") */

((int *)(BufferSend))[0] = 0x5002;

/* Заполнение сообщения */

strcpy(BufferSend + 4, "Так вот ты какой, Менеджер Ресурсов!");

if (MsgSend(fdRM, BufferSend, 100, BufferReply, 100) == -1)

printf("Клиенту не удалось передать сообщение\n");

else

printf("Клиент передал сообщение и получил <%s>\n", BufferReply);

fflush(stdout);

close(fdRM);

return(0);

}

Код процесса-сервера (менеджера ресурсов)

Для запуска сервера

на удаленном узле выполните с терминала команду:

# on -f /net/Bed-Test /net/904-3/home/ZZZ/BIN/TestMGR

где

Bed-Test
— имя удаленного узла,
904-3
— имя локального узла,
/home/ZZZ/BIN/TestMGR
— путь к исполняемому файлу.

Вначале сервер выполняет действия по своей инициализации, специфические для данного процесса. Если они завершились успешно, т.е. сервер готов обслуживать клиентов, он инициализирует себя как администратор устройства (функции

dispatch_create
,
memset(&resmgr_attr, ...)
,
iofunc_func_init
,
resmgr_attach
,
message_attach
,
dispatch_context_alloc
), при этом на том узле, где запущен менеджер, появляется файл
/dev/MESSTEST/RM
. После этого, если все прошло успешно, сервер выходит на бесконечную петлю приема сообщений.

Прием сообщений осуществляется функцией

dispatch_block
, блокирующей процесс-сервер на ожидании сообщений. При получении сообщения оно передается функции
dispatch_handler
, которая производит разборку сообщения. Если это сообщение относится к известным разборщику, оно направляется к соответствующей функции обработки, принимаемой по умолчанию.

Так, в частности, обрабатываются сообщения на открытие ресурса (пересылаемое клиентом при вызове им функции

open
), на отсоединение и закрытие ресурса (отсылаются клиентом при вызове им функции
close
), на чтение или запись (если клиент вызовет функции
read
или
write
) и ряд других. Кроме того, разборщику известны сообщения, заголовок которых содержит «инвентаризационную метку», попадающую в диапазон, указанный при вызове функции присоединения приватных сообщений
message_attach
. В этом случае сообщение передается для дальнейшей обработки функции-обработчику приватных сообщений (в нашем примере это функция
PrivatHandler
).

При рассмотрении функции обработки приватных сообщений

PrivatHandler
следует обратить внимание, что, хотя в этой функции и предусмотрено освобождение клиента с Reply-блокировки, она возвращает не
_RESMGR_NOREPLY
, как можно было бы ожидать, а значение
0
, что указывает библиотеке менеджера ресурсов на то, что отвечать Reply-сообщением клиенту уже нет необходимости. Это объясняется тем, что обработчик приватных сообщений сам выполняет Reply-сообщение, и это заложено в нем изначально. В этом состоит важное отличие этого обработчика от всех прочих (взгляните на код обработчика
prior_read
в разделе «Менеджеры ресурсов» главы 5).

Еще одна тонкость: при работе с приватными сообщениями в процессе-менеджере необходимо использовать функции диспетчеризации

dispatch_*
(
dispatch_block
,
dispatch_handler
и т.д.), а не функции менеджера ресурсов
resmgr_*
(
resmgr_block
,
resmgr_handler
и т.д.).

#include <errno.h>

#include <stdio.h>

#include <stddef.h>

#include <stdlib.h>

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