Сигналы. Сетевая доставка сигналов. Системный вызов. Отправка сигнала процессу на удаленном узле. Программа приема сигнала, страница 11

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;

/************** Определение типов сообщений **************************/