ВЗАИМОДЕЙСТВИЕ ПРОЦЕССОВ ЧЕРЕЗ РАЗДЕЛЯЕМУЮ ПАМЯТЬ
Цель работы – знакомство с механизмом обмена данными между процессами – разделяемой памятью и с системными вызовами, обеспечивающими создание разделяемой памяти, отображения ее на локальную память, передачу данных, чтение данных, закрытие и удаление разделяемой памяти.
Общие сведения
Участок разделяемой памяти создается следующим вызовом:
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; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!