Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Comment.docx
Скачиваний:
0
Добавлен:
20.06.2023
Размер:
86.25 Кб
Скачать

Комментарии к работе 8

В этой работе также требуется написать две программы.

Одна пишет сообщения в очередь в неблокирующем режиме. Вторая читает сообщения из очереди в неблокирующем режиме.

Если будет запущена только одна из программ, то она должна корректно завершаться по нажатию клавиши.

Если при работе двух программ, одну завершили, вторая не должна аварийно завершаться.

Рассмотрим очередь стандарта POSIX. Эта очередь отсутствует в ОС macOS. Владельцам macOS придется использовать очередь system V, которая будет рассмотрена позже.

Для очереди POSIX желательно чтение раздела помощи:

man 7 mq_overview

и ознакомление с каталогом /proc/sys/fs/mqueue, где описаны параметры очередей.

Main части программ передачи и приема совпадают за исключением одного флага в функции создания (открытия) очереди. Обратите внимание на имя очереди – слэш должен быть:

передача:

mq_open("/myqueue",O_CREAT | O_WRONLY|O_NONBLOCK, 0644, NULL);

прием:

mq_open("/myqueue",O_CREAT | O_RDONLY|O_NONBLOCK, 0644, NULL);

Здесь в вызовах используются атрибуты по умолчанию. Желательно ознакомиться с функциями чтения и записи атрибутов очереди:

mq_getattr() и mq_setattr().

Например, вывести установленный размер очереди и установить какой-нибудь желаемый размер очереди.

Или флаги O_WRONLY и O_RDONLY установить через атрибуты.

Поскольку передачу и прием делаем неблокированными, необходимо анализировать результаты вызовов:

result = mq_send(mqid,buffer,len,0);

if (result == -1) {

perror(“mq_send”);

}else{

//OK!

}

result = mq_receive(mqid,buffer,size,0);

if (result > 0) {

cout << "mq_receive: result = " << result << " " << buffer << endl;

}else if (result == -1) {

perror(“mq_receive”);

sleep(1);

continue;

}

как и раньше при передаче – len – длина сообщения, при приеме size – размер буфера.

Если все перечисленные положения выполнить, то заданные в начале условия тоже выполнятся.

Очередь System V

Общая для двух программ очередь создается с помощью уникального ключа.

Уникальный ключ создается функцией ftok().

Первым параметром функции является имя какого-нибудь существующего файла, второй параметр – ненулевой идентификатор.

например

key = ftok(“lab81”,’A’);

Чтобы обе программы в части main() были одинаковыми, надо сначала сделать попытку открыть очередь.

Если ошибки нет, то переходим к созданию потока, если ошибка, то переходим к созданию очереди.

Это выглядит так:

msgid = msgget(key,0);//открываем

if (msgid < 0) {//ошибка открытия

msgid = msgget(key,0666|IPC_CREAT);//создаем

}

Для передачи сообщений надо создать структуру, например:

typedef struct {

long mtype;

char buff[256];

}TMessage;

Как подготовить структуру для передачи сообщения:

Объявим переменную

TMessage message;

В поле типа запишем число:

message.mtype = 1;

А в поле buff запишем сообщение (как уже делали):

len = sprintf(message.buff,"hello, %d",count);

Теперь можем передавать:

result = msgsnd(msgid,&message,len, IPC_NOWAIT);

IPC_NOWAIT – флаг снятия блокировки при передаче.

Поскольку блокировку сняли необходимо анализировать result !!!

Для приема создаем такую же структуру:

принимаем сообщения того же типа и готовим буфер для приема сообщения (очищаем):

TMessage message;

message.mtype = 1;

memset(message.buff,0,sizeof message.buff);

и принимаем

result = msgrcv(msgid,&message,sizeof(message.buff),message.mtype,IPC_NOWAIT);

С помощью функции

https://www.opennet.ru/man.shtml?topic=msgctl&category=2&russian=0

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

можно смотреть параметры очереди, например, размер.

А указав команду cmd = IPC_RMID и buf = NULL, надо удалить очередь в конце работы программы.

Соседние файлы в предмете Операционные системы