ВЗАИМОДЕЙСТВИЕ ПРОЦЕССОВ ЧЕРЕЗ РАЗДЕЛЯЕМУЮ ПАМЯТЬ



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

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

Участок разделяемой памяти создается следующим вызовом:

int shm_open(const char *name, int oflag, mode_t mode),

где name – имя участка разделяемой памяти; oflag – флаги, определяющие тип создаваемого участка разделяемой памяти; mode – права доступа к участку разделяемой памяти.

Установка размера участка разделяемой памяти производится следующим вызовом:

int ftruncate(int fd, off_t length),

где fd - дескриптор разделяемой памяти, полученный как результат вызова функции shm_open(); length – требуемый размер разделяемой памяти.

Отображение разделяемой памяти на локальный адрес создается вызовом:

void *mmap(void *addr,

size_t length,

int prot,

int flags,

int fd,

off_t offset),

где addr - начальный адрес отображения; length - размер отображения; prot – параметр, определяющий права чтения/записи отображения; flags – параметр, определяющий правила видимости отображения процессами; fd - дескриптор разделяемой памяти; offset – смещение на участке разделяемой памяти относительно начального адреса.

Удаление отображения разделяемой памяти на локальный адрес производится вызовом:

int munmap(void *addr, size_t length),

где addr – локальный адрес отображения; length - размер отображения.

Закрытие участка разделяемой памяти производится вызовом:

int close(int fd),

где fd - дескриптор разделяемой памяти.

Удаление участка разделяемой памяти производится вызовом:

int shm_unlink(const char *name),

где name – имя участка разделяемой памяти.

Указания к выполнению работы

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

 

Шаблон программы 1 представлен ниже:

объявить флаг завершения потока;

объявить идентификатор семафора записи;

объявить идентификатор семафора чтения;

объявить идентификатор разделяемой памяти;

объявить локальный адрес;

Функция потока()

{

объявить переменную;

Пока (флаг завершения потока не установлен)

{

присвоить переменной случайное значение;

вывести значение переменной на экран;

скопировать значение переменной в локальный адрес;

освободить семафор записи;

ждать семафора чтения;

задержать на время;

}

}

Основная программа()

{

объявить идентификатор потока;

создать (или открыть, если существует) разделяемую память;

обрезать разделяемую память до требуемого размера;

отобразить разделяемую память на локальный адрес;

создать (или открыть, если существует) семафор записи;

создать (или открыть, если существует) семафор чтения;

создать поток из функции потока;

ждать нажатия клавиши;

установить флаг завершения потока;

ждать завершения потока;

закрыть семафор чтения;

удалить семафор чтения;

закрыть семафор записи;

удалить семафор записи;

закрыть отображение разделяемой памяти на локальный адрес;

удалить разделяемую память;

}

 

Шаблон программы 2 представлен ниже:

объявить флаг завершения потока;

объявить идентификатор семафора записи;

объявить идентификатор семафора чтения;

объявить идентификатор разделяемой памяти;

объявить локальный адрес;

Функция потока()

{

объявить переменную;

Пока (флаг завершения потока не установлен)

{

ждать семафора записи;

скопировать данные из локального адреса в переменную;

вывести значение переменной на экран;

освободить семафор чтения;

}

}

Основная программа()

{

объявить идентификатор потока;

создать (или открыть, если существует) разделяемую память;

изменить размер разделяемой памяти на требуемый;

отобразить разделяемую память на локальный адрес;

создать (или открыть, если существует) семафор записи;

создать (или открыть, если существует) семафор чтения;

создать поток из функции потока;

ждать нажатия клавиши;

установить флаг завершения потока;

ждать завершения потока;

закрыть семафор чтения;

удалить семафор чтения;

закрыть семафор записи;

удалить семафор записи;

закрыть отображение разделяемой памяти на локальный адрес;

удалить разделяемую память;

}

Вопросы для самопроверки

1. Какие программные интерфейсы существуют для получения участка разделяемой памяти?

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

3. На основе какого параметра функции открытия разделяемой памяти один и тот же участок становится доступным из разных процессов?

4. Каким образом участок глобальной разделяемой памяти, описываемой идентификатором, становится доступным в адресном пространстве программы?

5. С какой целью в предлагаемых шаблонах программ используется пара семафоров – семафор записи и семафор чтения?

6. Сразу при создании участок разделяемой памяти получает нулевую длину. Каким образом впоследствии обеспечивается возможность записи данных в этот участок?

 


Дата добавления: 2018-04-05; просмотров: 684; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!