n = mq_receive( msg_queue_id_rd, buff, max_len, &prio );
if ( n < 0 ) {
printf( "Client: message receive error!!!\n" );
exit(6);
}
mq_close( msg_queue_id_rd );
buff[n] = '\0';
printf( "Client: message received, length = %d\n", n );
printf( "Message: %s. ", buff );
printf( "Prio: %d\n", prio );
// Освобождаем выделенную память //
free( buff );
return EXIT_SUCCESS;
}
Результаты работы приложения. Результаты работы программы. Программы запускались прямо из IDE(Run As C/C++ QNX Application). Результаты работы выводятся на консоль в IDE.
Аргументы командной строки для клиента задавались в Run Configuration->Arguments->”server_queue 10”. Первый аргумент — имя файла очереди сообщений, второй приоритет передаваемого сообщений
Сервер |
Клиент |
Server: start. Server: message received, length = 3 Message: 123 Prio: 2 |
Client: connect is OK. Message: 123 Client: send message is OK. Client: message received, length = 2 Message: OK. Prio: 31 |
Профилирование приложения. Timeline-диаграммы и Trace Log клиента и сервера.
По Trace Log видно, что сообщения POSIX реализованы через нативные механизмы IPC микроядра QNX.
С помощью функций MsgSend(), MsgReceive(), MsgReply() происходит взаимодействие с сервером (или менеджером ресурсов) очередей сообщений POSIX — mqueue. При записи/чтении из очереди сообщений происходит обмен сообщениями процесса с mqueue.
7. Агентная модель.
Структура агентной модели.
Рис. 2.5.1. Структура агентной модели.
В данном случае, в отличии от обычной клиент-серверной модели, запросы клиентов выполняет не один сервер, а множество агентов. Сервер выполняет только связывающую роль и непосредственно не занимается обработкой запросов.
Сервер порождает заданное число процессов-агентов, при запуске агенты регистрируются посылая серверу сообщение определенного типа и находятся в Reply-блокированном состоянии, ожидая от сервера ответа.
При поступлении запроса от клиента сервер просто пересылает запрос агенту, и обратно результат работы агента клиенту.
Если свободных агентов нет, то клиенты ставятся в очередь.
Схема программы сервера агентной модели.
Листинг 7.1. Определение форматов сообщений. Файл defs.h.
#ifndef DEFS_H_
#define DEFS_H_
#define ATTACH_POINT "qnx_msg_server"
#define BUF_LEN 256
#define QUEUE_LEN 256
/************** Определение форматов сообщений **********************/
typedef struct ClientMsg_T {
int type;
char msg_buff[ BUF_LEN ];
} ClientMsg_T;
typedef struct AgentMsg_T {
int type;
char msg_buff[ BUF_LEN ];
int client_rcvid;
} AgentMsg_T;
typedef union {
struct _pulse PulseMsg;
struct AgentMsg_T AgentMsg;
struct ClientMsg_T ClientMsg;
} Msg_T;
/************** Структура с информацией об агенте ********************/
typedef struct AgentInfo
{
pid_t pid; // Идентификатор процесса
int recv_id; // Идентификатор для обмена сообщениями
int busy; // Занят или свободен
char file_name[256]; // Имя исполняемого файла
} AgentInfo;
/************** Структура с информацией об клиенте *******************/
typedef struct ClientInfo
{
int recv_id; // Идентификатор для обмена сообщениями
char msg_buf[ BUF_LEN ]; // Сообщение
} ClientInfo;
/************** Очередь с клиентами **********************************/
typedef struct ClientQueue
{
int puts;
int index;
struct
ClientInfo ClientBuf[ QUEUE_LEN ];
} ClientQueue;
/************** Определение типов сообщений **************************/
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.