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

ЖАНРЫ

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

attr - инициализированная выше структура атрибутов устройства.

Подключаем диапазон сообщений, которые должны рассматриваться как

приватные, с передачей их обработчику для таких сообщений -

PrivatHandler */

if (message_attach(dpp, NULL, 0x5000, 0x5fff, &PrivatHandler, NULL) == -1) {

printf("невозможно подключить данный "

"диапазон приватных сообщений\n");

return(EXIT_FAILURE);

}

/*
Размещение контекстной структуры */

ctp = dispatch_context_alloc(dpp);

/* Размер буфера сообщений, содержащегося а этой структуре, равно как и

число векторов ввода/вывода, также содержащихся в этой структуре,

установлены при инициализации структуры атрибутов менеджера ресурсов */

/* Запуск петли сообщений менеджера ресурсов */

while(1) {

// ожидание прихода сообщений

if ((ctp = dispatch_block(ctp)) == NULL) {

printf("ошибка блока\n");

return EXIT_FAILURE;

}

printf("Менеджер ресурсов получил сообщение"

" длиной %i байт\n", ctp->resmgr_context.info.msglen);

result = dispatch_handler(ctp);

// сообщение раскодируется, и на основании заданных таблиц функций связи

// и ввода/вывода вызывается соответствующая функция обработки сообщения

if (result)

printf("Менеджер ресурсов не смог обработать"

" сообщение result = %i\n", result);

}

}

/********************************************************************

Обработчик приватных сообщений, то есть сообщений, заголовок которых

укладывается в диапазон, указанный при вызове функции message_attach

********************************************************************/

int PrivatHandler(message_context_t* ctp, int code,

unsigned flags, void* handle) {

char Buffer[MESSIZE_MAX];

printf("получено приватное сообщение тип %x от"

" \"%s\"\n", code, IdLabelParse(code));

printf("Вот это сообщение <<%s>>\n",

(char *)(ctp->msg) + 4);

strcpy(Buffer, "Клиенту: да, я такой");

MsgReply(ctp->rcvid, EOK, Buffer, sizeof(Buffer));

return(0);

}

/********************************************************************

Функция пользовательской библиотеки, определяющая инвентаризационное

имя
процесса по его инвентаризационной метке

********************************************************************/

char* IdLabelParse(int id) {

struct IdLabel_t Inventory;

int i = 0;

while (IdLabel[i].id != id && i < ALLNUM_MYPROC) i++;

if (i == ALLNUM_MYPROC) return Anonymous;

else return(IdLabel[i].name);

}

Использование менеджера службы глобальных имен

Начиная с QNX версии 6.3 сервис глобальных имен, обеспечиваемый GNS-менеджером службы (утилитой

gns
), действует в сети. Используя этот сервис, нет необходимости организовывать программу как полноценный менеджер ресурсов, при этом приложение-сервер может объявлять свою службу, а приложения-клиенты могут отыскивать и использовать службы через QNET-сеть без знания таких частностей, как, например, где эта служба располагается и кто ее обеспечивает. Подробно о сервисе глобальных имен см. в [4].

Для того чтобы развернуть этот сервис, необходимо в режиме сервера запустить менеджер службы глобальных имен на том узле, где должно работать наше приложение-сервер. В режиме сервера GNS-менеджер выступает в роли некой центральной базы данных, хранящей объявленные службы, и обрабатывает запросы на поиск и установление связи с ними. На узле же, где располагается клиент, запускаем менеджер в режиме клиента, при этом он передает запросы объявления, поиска и установки связи между локальным (то есть расположенным на этом же узле) приложением-клиентом и сервером (серверами)

gns
.

Серверный узел:

# gns -s

Клиентский узел (узлы):

# gns -с

В результате на узлах, где запущены службы глобальных имен, появятся имена

/dev/name/global
и
/dev/name/local
. Каждый узел, на котором запущен gns-клиент или сервер, в одной и той же сети имеет один и тот же вид пространства имен на
/dev/name/global
. Каждый узел имеет локальное пространство имен
/dev/name/local
, являющееся локальным для данной машины и отличающееся от локального пространства имен на другой машине. (Кстати, помимо имен
global
и
local
под
/dev/name/
появится еще имя
gns_server
или
gns_local
— имя, под которым регистрируется сам GNS-менеджер.)

Существует несколько функций API, относящихся к службе глобальных имен:

name_attach
,
name_open
и
name_close
. Программисты, знакомые с QNX 4, сразу «узнают» в них аналоги известных им функций
qnx_name_attach
,
qnx_name_open
и
qnx_name_close
. Приложения используют эти функции для объявления имени службы, связи со службой и отсоединения от службы.

Итак, чтобы объявить свое имя глобально в сети, приложение-сервер должно на узле, где в режиме сервера функционирует менеджер службы глобальных имен, объявить свою службу, выполнив вызов:

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