Санкт-Петербургский государственный политехнический университет
Факультет технической кибернетики
Кафедра компьютерных систем и программных технологий
ОТЧЁТ
по лабораторной работе
Дисциплина: Системное программное обеспечение
Тема: Обмен сообщениями и импульсами в ОС QNX
Работу выполнил студент группы 4081/1
Преподаватель Е.
подпись
Санкт-Петербург
2010
1. Обмен сообщениями
В работе исследовался обмен сообщениями при стандартной организации модели "клиент-сервер", управляемой по запросу. При такой модели сервер первоначально ждёт сообщения, находясь в состоянии блокировки по приёму (receive-blocked). При получении сообщения сервер переходит в состояние готовности (ready) и становится способен выполнять работу. После обработки сообщения сервер посылает ответ клиенту.
Рис. 1.1. Смена состояний сервера
При посылке сообщения клиент переходит из состояния готовности (ready) либо в состояние блокировки по приему (reply-blocked) (сервер принял сообщение и обрабатывает его), либо в состояние блокировки по передаче (send-blocked) (сервер ещё не принял сообщение).
Рис. 1.2. Смена состояний клиента
Часто используют многопоточную реализацию с помощью семейства функций thread_pool_*(), при которой каждый из потоков способен обрабатывать сообщения от клиентов. Такая реализация наиболее эффективна в многопроцессорных системах.
Рис. 1.3. Обслуживание клиентов различными потоками сервера
Также применяется модель «сервер/субсервер», в которой несколько субсерверов посылают сообщения серверу, но сервер отвечает им только по мере запросов от клиентов. В итоге сообщения клиентов передаются субсерверам, которые выполняют их обработку.
Благодаря такой модели сервер сам не обрабатывает сообщения и может продолжать принимать запросы от клиентов. Модель полезна при использовании распределённых систем.
Рис. 1.4. Модель «сервер/субсервер»
1.1. Передача сообщений между двумя родственными процессами
Рассмотрим передачу сообщений между двумя родственными процессами. Процесс-сервер порождает три дочерних процесса, которые будут являться клиентами. Они отправляют сообщение, затем получают ответ от сервера.
Программа server.c:
#include <sys/neutrino.h>
#include <errno.h>
#include <process.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (void) {
// Идентификаторы соединения и клиента
int chid, rcvid;
// Счётчик принятых сообщений
int i;
// Приёмный буфер и буфер для ответа
char receive_buf[50], reply_buf[50];
// Создание канала
chid = ChannelCreate(0);
// Порождение дочерних процессов-клиентов
spawnl(P_NOWAIT, "client", "client", NULL);
sleep(2);
spawnl(P_NOWAIT, "client", "client", NULL);
sleep(2);
spawnl(P_NOWAIT, "client", "client", NULL);
sleep(2);
for (i = 0; i < 3; i++) {
// Принимаем сообщение
rcvid = MsgReceive(chid, &receive_buf, sizeof(receive_buf), NULL);
// Если не импульс, обрабатываем сообщение
if (rcvid) {
// Выведем текст принятого сообщения
printf("SERVER: message from client \"%s\"\n", &receive_buf );
// Запишем в буфер ответа сообщение для клиента
sprintf(reply_buf, "Reply from server to client", rcvid);
// Отправим ответ
printf("SERVER: send message to client \"%s\"\n", &reply_buf );
MsgReply(rcvid, EOK, &reply_buf, sizeof(reply_buf));
}
}
// Уничтожаем канал
ChannelDestroy(chid);
return EXIT_SUCCESS;
}
Программа client.c:
#include <sys/neutrino.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main () {
// Идентификатор соединения
int coid;
// Возвращаемое значение MsgSend
int status;
// PID текущего процесса и процесса-сервера
int pid = getpid(), server_pid = getppid();
// Буферы для отправляемого и принимаемого сообщений
char send_buf[50], reply_buf[50];
// Устанавливаем соединение с сервером
coid = ConnectAttach(0, server_pid, 2, 0, 0);
// Запишем в буфер текст сообщения для сервера
sprintf(send_buf, "Hello from client with PID = %d", pid);
// Отправляем сообщение и принимаем ответ
printf("Client: send message \"%s\"\n", &send_buf );
status = MsgSend(coid, &send_buf, sizeof(send_buf), &reply_buf, sizeof(reply_buf));
if (status == -1) {
printf("Error of MsgSend\n");
return EXIT_FAILURE;
}
printf("Client: message \"%s\" from server\n", &reply_buf);
// Закрываем соединение
ConnectDetach(coid);
return EXIT_SUCCESS;
}
Использованные функции:
1) На стороне сервера
#include <sys/neutrino.h>
int ChannelCreate( unsigned flags ); - создание канала
int MsgReceive( int chid,
void * msg,
int bytes,
struct _msg_info * info ); - принятие сообщения
int MsgReply( int rcvid,
int status,
const void* msg,
int size ); - ответ клиенту
2) На стороне клиента
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.