Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
методичка ПП.pdf
Скачиваний:
8
Добавлен:
02.06.2015
Размер:
288.49 Кб
Скачать

Цель работы: знакомство с механизмом обмена данными через канал и системными вызовами, обеспечивающими такой обмен.

6.1. Общие сведения

Программный канал - это механизм межпроцессорного обмена через общий буфер. Отличительной чертой такого обмена является то, что этот буфер рассматривается как файл и к нему применимы все операции ввода/вывода файловой системы. Открывает канал системная функция int pipe (int fildes[2]). При успешном завершении функция возвратит 0, а при ошибки -1. Ее параметром является адрес массива из двух целых переменных, в котором после выполнения функции будут храниться номера двух дескрипторов файлов: для чтения из канала и для записи в канал. Читать данные из канала можно через номер дескриптора fildes[0], а записывать данные в канал можно через номер дескриптора fildes[1]. Канал открывается процессом предком и наследуется потомками.

Запись в канал осуществляется с помощью функции int write (int fildes, char * buf, size_t count). Функция записывает в конец буфера открытого канала данные из области, адрес которой задан в параметре buf. Число записываемых байтов указывается в параметре count. Параметру fildes должен соответствовать номер дескриптора файла, через который можно выполнять запись. Если канал не занят другим процессом и объем данных не превышает свободной области буфера, то все они записываются в канал. При наложении операций и при отсутствии в буфере свободного пространства процесс не перейдет в состояние ожидания, если для файла будет установлен флаг O_NONBLOCK. В этом случае операция записи в канал прерывается и возвращается код ошибки. Данные, объем которых не превышает размера буфера (4 Кбайт), никогда не прерываются данными, записываемыми в канал другими процессами. Запись большего числа байт может привести к перемешиванию данных от разных процессов, так как такая операция записи разделяется на части. В этом случае данные в канал записывается порциями, в зависимости от свободного пространства в буфере.

Чтение данных из канала осуществляет функция int read (int fildes, char * buf, size_t count). Эта функция выполняется только при условии, что буфер канала не пуст. Она читает из буфера канала количество байт, указанных в параметре count, и пересылает их в область, адрес которой определен в параметре buf. Параметру fildes должен соответствовать номер дескриптора файла, через который можно выполнять чтение из канала. Если буфер пуст и установлен флаг O_NONBLOCK, то функция завершается и возвращает значение 0. При этом же установленном флаге и запрещении записи в канал или пересечении с выполнением другой операции с каналом функция возвратит -1. Если флаг O_NONBLOCK не установлен и буфер пуст или другой процесс начал выполнять операцию с каналом, то текущий процесс переходит в состояние ожидания, пока другой процесс не запишет в канал данные или не завершит операцию.

18 - -

Для завершения работы с каналом используется функция int close (int fildes). Ее параметром является номер дескриптора закрываемого файла.

6.2. Подготовка к работе

Задание 1. Написать программу, в которой предок порождает двух потомков. Оба потомка читают символы из разных файлов и записывают их в один канал. Предок читает данные из канала и выводит их на экран.

Задание 2. Написать программу , в которой порождаются два потомка и предок обменивается данными с потомками через канал. Предок читает данные из файла и посимвольно записывает их в канал. Потомки поочередно читают данные из канала и выводят их на экран. Первый потомок - четные символы, а второй - нечетные. Синхронизация работы потомков осуществляется с помощью сигналов.

6.3. Порядок выполнения работы

1.Вызвать текстовый редактор и набрать программу и файл исходных данных.

2.Откомпилировать программу и получить загрузочный модуль.

3.Запустить программу и по результатам вывода на экран убедиться в правильности

ееработы.

6.4.Содержание отчета

Отчет по лабораторной работе должен содержать листинг программы с комментариями.

6.5. Защита работы

Для защиты лабораторной работы студенту необходимо знать: особенности механизма обмена данными через канал; набор системных вызовов и порядок их использования для обмена данными через канал.

6.6. Контрольные вопросы

1.При каких условиях канал не будет работать?

2.Как будут вести себя процессы при одновременном обращении к каналу?

3.Можно ли записывать в канал и читать из канала данные, объем которых превышает размер буфера канала?

Лабораторная работа 7 ВЗАИМОДЕЙСТВИЕ ПРОЦЕССОВ НА ОСНОВЕ СООБЩЕНИЙ

19 - -

Цель работы: знакомство с механизмом межпроцессных коммуникаций и системными вызовами приема и передачи сообщений.

7.1. Общие сведения

Механизм межпроцессных сообщений используется для синхронизации и обмена данными между процессами. Отличительной чертой этого механизма является возможность взаимодействия процессов, не связанных родственными отношениями. Обмен данными осуществляется через порт, который представляет собой очередь сообщений. Для приема или передачи сообщения процесс прежде всего должен запросить у ОС порт. Эта операция выполняется с помощью системной функции int msgget (key_t key, int msgflg ). Данная функция при успешном завершении своей работы возвратит идентификатор, по которому в дальнейшем процесс будет обращатся к порту, а при неудачном завершении возвратит -1. Первый параметр функции может принимать два значения: константа IPC_PRIVATE или целое ненулевое положительное число, являющееся ключом порта. Второй параметр функции msgget представляет собой набор флагов, определяющих режим работы функции и права доступа к порту. Процессы, использующие для работы один и тот же порт, должны вызвать эту функцию с одинаковым ключом и с флагом IPC_CREAT. Установка одновременно нескольких флагов выполняется посредством операции простого или логического сложения. Права доступа к порту задаются с помощью флагов, которые в восьмеричной системе счисления имеют следующие значения: 0400 - разрешен прием сообщений пользователю, владеющему портом; 0200 - разрешена передача сообщений пользователю, владеющему портом; 0040 - разрешен прием сообщений пользователям, входящим в ту же группу, что и владелец порта; 0020 - разрешена передача сообщений пользователям, входящим в ту же группу, что и владелец порта; 0004 - разрешен прием сообщений всем остальным пользователям; 0002 - разрешена передача сообщений всем остальным пользователям.

Функция msgget может не только выделять порт по заданному ключу, но и проверять наличие в системе порта с таким же ключом. Для этого наряду с флагом IPC_CREAT надо задать флаг IPC_EXCL. В этом случае функция возвратит идентификатор порта только при условии, что порт с таким ключом еще ни одному процессу не выделен. Если порт с указанным ключом уже выделен какому-либо процессу, то функция возвратит -1.

Передача сообщения осуществляется системной функцией int msgsnd (int msqid, struct msgbuf *msgp, int msgsz, int msgflg). Для выполнения этой функции требуется задать четыре параметра: msgid - идентификатор порта, в который посылается сообщение; msgp - адрес буфера, где располагается передаваемое сообщение; msgsz - длина передаваемого сообщения, которая не должна превышать 4056 байт; msgflg - флаг, определяющий режим выполнения операции. Поле msgflg может иметь значение либо 0,

20 - -

либо IPC_NOWAIT. Флаг IPC_NOWAIT означает, что в случае невозможности передачи сообщения в порт ( превышено максимально допустимое количество данных в порте - 16384) процесс не будет ждать, пока появится возможность передать сообщение, а продолжит работу, при этом функция msgsnd возвратит -1. При успешном завершении функция записывает сообщение в конец очереди и возвращает 0. Сообщение будет находиться в очереди пока другой процесс не примет его.

Прием сообщения выполняется путем обращения к системной функции int msgrcv (int msqid, struct msgbuf *msgp, int msgsz, long msgtyp, int msgflg). Одноименные параметры данной функции имеют такое же назначение, как и в функции msgsnd. Правило поиска сообщения в порте определяется параметром msgtyp. Если он равен нулю, то будет выбрано первое сообщение из очереди независимо от его типа. При положительном значении этого параметра из очереди будет выбрано первое сообщение, у которого тип совпадает со значением параметра, если не установлен флаг MSG_EXCEPT, или первое сообщение, у которого тип не совпадает со значением параметра, если установлен флаг MSG_EXCEPT. Отрицательное значение параметра msgtyp указывает, что требуется найти в очереди первое сообщение, у которого значение типа не превышает абсолютного значения параметра.

Пользователь может осуществлять контроль за состоянием порта. Этот контроль выполняется с помощью системной функции int msgctl (int msqid, int cmd, struct msqid_ds *buf). Режим работы функции определяется параметром cmd, который может принимать одно из следующих значений:

IPC_STAT - функция возвратит информацию о порте в структуру, адрес которой должен быть задан в параметре buf.

IPC_SET - функция изменяет права доступа к порту и объем данных, который может храниться в порте. Новые значения должны быть заданы в соответствующих полях параметра buf.

IPC_RMID - полное уничтожение порта и всех содержащихся в нем сообщений. Процессы, ожидающие приема или передачи сообщения из данного порта, продолжат свое выполнение. Изменение и уничтожение порта разрешается только суперпользователю и владельцу порта. Если процесс не уничтожит свой порт, то последний остается зарегистрированным в системе и после завершения задачи.

7.2. Подготовка к работе

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

21 - -