printf("Ребенок: установил связь coid = %i с процессом"
" Parpid = %i на узле %i\n", coid, Parpid, nid);
// Вот здесь хорошее место, чтобы выполнить все действия,
// необходимые для развертывания данного процесса
itoa(CChanid, SendBuf, 10);
errno = 0;
if (MsgSend(coid, SendBuf, 100, SendBuf, 100) == -1)
printf("Ребенок: на MsgSend к отцу получил"
" errno = %i\n", errno);
else
printf("Ребенок: на MsgSend получен отклик"
" от родителя.\"%s\"\n", SendBuf);
rcvid = MsgReceive(CChanid, RecBuf, 100, NULL);
printf("Ребенок:
от папани получено сообщение:"
" \"%s\"\n", RecBuf);
strcpy(RecBuf, "я здесь, папаня!");
if (MsgReply(rcvid, EOK, RecBuf, 100) == -1)
printf("Ребенок: почему-то не удалось ответить"
" папаше. Ау, где ты?\n");
printf("Ребенок: дитятко работу закончило\n");
ChannelDestroy(CChanid);
ConnectDetach(coid);
return(0);
}
Обмен сообщениями на основе менеджера ресурсов
Описанный выше способ построения функционирующей в сети системы процессов может быть реализован далеко не всегда. Зачастую клиенту не известна полная триада, позволяющая ему создать соединение с сервером. Вспомним, что в QNX 4, где для создания связи с другим процессом был необходим его идентификатор, существовала служба пространства имен, обеспечиваемая сервером службы
nameloc
. Сервер объявлял свое имя в пространстве имен с помощью функции
qnx_name_attach
, а затем клиент, вызвав функцию
qnx_name_locate
, получал от системы идентификатор сервера, по которому мог далее с ним общаться.
Разработчики QNX 6 настоятельно рекомендуют вместо использования службы имен выполнять сервер в виде менеджера ресурсов, причем настолько настоятельно, что до версии 6.3 аналог этой службы — менеджер службы глобальных имен
gns
— функционировал только локально. И надо признать, что мощь и изящество менеджера ресурсов являются очень убедительным подкреплением этих рекомендаций.
При использовании механизма менеджера ресурсов процесс, выступающий в качестве сервера, регистрирует свой так называемый префикс путевого имени файла в пространстве файловых имен, после чего другие процессы (клиенты) могут открывать это имя как файл, используя стандартную библиотечную функцию
open
. Получив в результате выполнения этой функции дескриптор файла, они затем могут обращаться к серверу, используя стандартные библиотечные функции С, такие как
read
,
write
и т.д.
Однако важным (по крайней мере, для программистов, не желающих отказываться от такого привычного и эффективного механизма передачи данных, как обмен сообщениями) является тот факт, что этот дескриптор на самом деле является не чем иным, как идентификатором соединения. И поэтому к серверу можно обращаться не только через высокоуровневые функции работы с файлами, но и с помощью элементарных функций обмена сообщениями
MsgSend*
(элементарных, напомню, в том смысле, что в действительности все стандартные высокоуровневые функции работы с файлами реализованы через функции обмена сообщениями).