Обмен сообщениями и импульсами в ОС QNX. Обмен сообщениями при стандартной организации модели "клиент-сервер", управляемой по запросу, страница 9

rcvid = clients[num_clients - 1];

num_clients--;

send_to_agent();

}

}

} else{

// Сообщение от клиента

printf(" from client\n");

if (num_agents > 0)  {

// Если есть свободные агенты

send_to_agent();

}

else {

// Нет свободных агентов, ставим клиента в очередь

clients[num_clients] = rcvid;

num_clients++;

}

}

}

}

// Уничтожаем канал 

name_detach(attach, 0);

return EXIT_SUCCESS;

}

void send_to_agent() {

printf("Server: send message to agent %d\n", num_agents);

itoa(rcvid, msg, 10);

num_agents--;

MsgReply(agents[num_agents], 0, &msg, sizeof(10));

}

Программа client6.c:

#include <stdlib.h>

#include <stdio.h>

#include <sys/dispatch.h>

#include <sys/iofunc.h>

#include <sys/neutrino.h>

#define SERV_NAME "channel"

int main() {

int fd;

char send_buf[200], reply_buf[200];

// Подключение к каналу

if ((fd = name_open(SERV_NAME, 0)) == -1) {

printf("Client: name_open() error\n" );

return EXIT_FAILURE;

}

strcpy(send_buf, "Hello");

// Отправляем сообщение   

MsgSend(fd, &send_buf, sizeof(send_buf), &reply_buf, sizeof(reply_buf) );

printf("Client: received \"%s\"\n", reply_buf);

// Отсоединяемся

name_close(fd);

return EXIT_SUCCESS;

}

Программа agent6.c:

#include <stdlib.h>

#include <stdio.h>

#include <sys/dispatch.h>

#include <sys/iofunc.h>

#include <sys/neutrino.h>

#define SERV_NAME "channel"

int main(){

int fd;

char send_buf[200], reply_buf[200];

// Подключение к каналу

if ( (fd = name_open(SERV_NAME, 0)) == -1) {

printf("Agent: name_open() error\n" );

return EXIT_FAILURE;

}

strcpy(send_buf, "agent" );

printf("Agent: hello\n");

while (1) {

// Принимаем сообщение

MsgSend(fd, &send_buf, sizeof(send_buf), &reply_buf, sizeof(reply_buf));

printf("Agent: received message \"%s\"\n", reply_buf);

// Имитируем обоработку

sleep(3);

// Формируем новое сообщение

sprintf(send_buf, "agent %s Hello_from_agent!", reply_buf);

}   

// Отсоединяемся

name_close(fd);

return EXIT_SUCCESS;

}

Запустим сервер (рис. 1.13).

Рис. 1.13. Результат запуска сервера

Сервер и агенты запущены, агенты отправили сообщение серверу в ожидании ответа. Сейчас они находятся в reply-блокированном состоянии (рис. 1.14).

Рис. 1.14. Reply-blocked агенты

Добавим нескольких клиентов (не более пяти), чтобы из них не образовалась очередь (рис. 1.15).

Рис. 1.15. Обработка сообщений клиентов

Клиенты отправили сообщения серверу, он, получив их, передаёт агентам идентификаторы клиентов. Агенты, получив сообщение от сервера, имитируют обработку данных, после чего отправляют ему результат. Сервер передаёт сообщение от агентов клиентам, после чего те отключаются.

Рассмотрим случай, когда клиентов будет больше пяти, чтобы получилась очередь (рис. 1.16).

Рис. 1.16. Обработка сообщений клиентов

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

Выводы

В данной работе рассматривалась наиболее характерная отличительная особенность QNX - механизм обмена сообщениями. Обмен сообщениями в QNX - ключевой механизм, глубоко интегрированный с микроядерной архитектурой этой операционной системы и обеспечивающий ей её модульность.

Была продемонстрирована суть моделей «клиент/сервер» и «сервер/субсервер». Первая модель является управляемой по запросу (send-driven), поскольку работа начинается с передачи сообщения серверу. Вторая - управляемой по ответу (reply-driven), так как выполнение задания начинается с ответа субсерверу.