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

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

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

-если файл программой прочитан, то сразу передается ответ;

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

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

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

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

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

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

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

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

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

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

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

1.В чем разница между идентификатором и ключом порта?

2.Как проверить существование порта с определенным ключом?

3.Какие изменения можно вносить в описание порта?

4.Как узнать, есть ли процессы ожидающие приема или передачи сообщения в порт?

22 - -

Лабораторная работа 8 ВЗАИМОДЕЙСТВИЕ ПРОЦЕССОВ ЧЕРЕЗ РАЗДЕЛЯЕМУЮ ПАМЯТЬ

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

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

Механизм разделяемой памяти применяется, когда процессы должны обмениваться большими объемами данных, и для организации общих переменных, посредством которых решается задача взаимоисключения при работе с разделяемым ресурсом. Суть этого механизма состоит в том, что в системной области выделяется память, которая затем может включаться в виртуальное адресное пространство разных процессов. В этом случае процессы получают возможность писать и читать в общую память, но обращаются к ней по своему виртуальному адресу.

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

Для включения разделяемой памяти в адресное пространство процесса используется функция char * shmat( int shmid, char * shmaddr, int shmflg). Результатом работы этой функции является указатель на первый байт разделяемой памяти. Если при выполнении функции будет обнаружена ошибка, то она возвратит -1. В первом аргументе функции указывается идентификатор разделяемого сегмента, во втором -либо 0, либо виртуальный адрес, по которому должен быть размещен сегмент. При нулевых значениях второго и третьего аргументов система самостоятельно разместит сегмент в виртуальном адресном

пространстве процесса и возвратит указатель на ее начало.

23 - -

Открепить разделяемую память от процесса можно путем вызова функции shmdt( char * shmaddr). Ее параметром является начальный виртуальный адрес разделяемой памяти, полученный при обращении к функции shmmat. При успешной работе функция возвратит 0, в противном случае -1.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

24 - -

1.Когда при запросе на разделяемую память используются флаги IPC_PRIVATE и IPC_CREAT ?

2.Каким образом можно защитить разделяемую память от записи?

3.Как узнать, какие процессы работают с разделяемой памятью?

Лабораторная работа 9 СИНХРОНИЗАЦИЯ ПРОЦЕССОВ С ПОМОЩЬЮ СЕМАФОРОВ

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

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

ВОС LINUX реализованы множественные семафоры. Множественный семафор - это объект специального типа, который одновременно доступен нескольким процессам и состоит из одного или нескольких простых семафоров. Он характеризуется идентификатором, ключом и количеством простых семафоров, включенных в него. Каждый простой семафор может принимать значение в диапазоне от 0 до 32767. Идентификатор множественного семафора использует процесс для указания, к какому из них применяется та или иная операция. Его значение генерирует система при создании множественного семафора. Ключ множественному семафору присваивает процесс, и по нему система выделяет разным процессам один и тот же семафор. Одновременно в системе могут существовать не более 128 множественных семафоров.

Вмножественный семафор могут входить не более 32 простых семафоров и каждый простой семафор может принимать значение в диапазоне от 0 до 32767. При этом значение простого семафора 0 соответствует закрытому состоянию семафора, положительное значение - открытому состоянию. Открыть простой семафор может команда инкрементирования, увеличивающая значение семафора, а закрыть семафор - команда декрементирования, которая может уменьшить значение семафора, но только до нуля. Кроме того, над простым семафором может выполняться команда проверки на нуль, что позволяет узнать, в каком состоянии находится семафор.

Для работы с множественными семафорами используются следующие системные функции:

int semget( key_t key, int nsems, int semflg) - выделение семафора. При успешном своем выполнении функция возвратит значение идентификатора множественного семафора, а в случае ошибки -1. Параметр key может принимать значение IPC_PRIVATE или являтся целым положительным числом, большим нуля, служащим ключом множественного семафора. Параметр nsems определяет количество простых семафоров,

содержащихся в множественном семафоре. Это число не должно превышать 32. В наборе

25 - -

флагов semflg задаются права доступа к множественному семафору и режим выполнения функции. Процессы, использующие для работы один и тот же семафор, должны вызвать эту функцию с одинаковым ключом и с флагом IPC_CREAT. Права доступа к множественному семафору задаются с помощью следующих восьмеричных констант: 0400 - владельцу разрешено читать характеристики семафора; 0200 - владельцу разрешено изменять характеристики семафора; 0040 - члену группы владельца разрешено

читать характеристики

семафора; 0020

- члену группы владельца разрешено

изменять характеристики

 

семафора; 0004 -

всем остальным пользователям

разрешено читать характеристики

семафора; 0002 -

всем остальным

пользователям разрешено изменять характеристики

 

семафора.

int semop( int semid, struct sembuf *sops, unsigned nsops) - операция с семафором.

Параметрами данной функции являются: идентификатор семафора(semid), адрес массива структур(sops), где располагается список команд для простых семафоров, и количество команд(nsops), которые надо выполнить из этого списка. Результаты выполнения функции могут быть представлены в следующих формах:

1.Если все команды из списка завершились успешно, то функция возвратит значение простого семафора, для которого применялась последняя команда из списка.

2.Если одна из команд списка завершилась неуспешно и для нее был установлен флаг IPC_NOWAIT, то выполнение операции будет прервано на этой команде и функция возвратит значение -1.

3.Если одна из команд списка завершилась неуспешно и для нее не был задан флаг IPC_NOWAIT, то операция прерывается, процесс переходит в состояние ожидания и становится в конец очереди семафора.

int semctl( int semid, int semnum, int cmd, union semun arg) - управление семафором. Функция имеет четыре аргумента: semid - идентификатор множественного семафора; semnum - номер простого семафора; cmd - режим работы функции; arg - структура данных типа объединение, в которую в зависимости от режима либо записываются входные данные для функции, либо передаются результаты ее выполнения. Тип union semun определен в библиотечном файле /sys/sem.h. Режим работы функции задается посредством следующих символических констант:

SETVAL - установка значения простого семафора. Для этой операции должны быть заданы номер простого семафора и значение в поле val в параметре arg;

GETVAL - определение значения простого семафора. По этой команде функция возвратит значение простого семафора, номер которого должен быть задан в аргументе semnum;

SETALL - установка значений для всех простых семафоров. Значения для всех простых семафоров предварительно записываются в массив, адрес которого указывается в поле array параметра arg. Параметр semnum в данном режиме не учитывается.

26 - -