Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ТОС_2013 / ТОС_9_м_пр_слайды.doc
Скачиваний:
11
Добавлен:
03.03.2016
Размер:
14.52 Mб
Скачать

Int *shmat( int shmid, char *shmaddr, int shmflag);

Вызов shmat() возвращает адрес начала области в адресном пространстве процесса размером size, заданным предшествующем вызовом shmget().

Правила получения этого адреса:

1. Если аргумент shmaddr нулевой, то система самостоятельно выбирает адрес.

2. Если аргумент shmaddr отличен от нуля, значение возвращаемого ад­реса зависит от наличия флажка SHM_RND в аргументе shmflag:

- Если флажок SHM_RND не установлен, система присоединяет разделяемую память к указанному shmaddr адресу.

- Если флажок SHM_RND установлен, система присоединяет разделяемую память к адресу, полученному округлением в меньшую сторону shmaddr до некоторой определенной величины SHMLBA.

По умолчанию разделяемая память присоединяется с правами на чтение и запись.

Эти права можно изменить, указав флажок SHM_RDONLY в аргументе shmflag.

Т.о., несколько процессов могут отображать область разделяе­мой памяти в различные участки собственного виртуального адресного пространства, как это показано на рис. 3.20.

Окончив работу с разделяемой памятью, процесс отключает (detach) об­ласть вызовом:

#include<sys/types.h>

#include<sys/ipc.h>

#include<sys/sem.h>

Int shmdt(char *shmaddr);

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

Примерная схема обмена данными между двумя процес­сами (клиентом и сервером) с использованием разделяемой памяти.

Для синхронизации процессов использована группа из двух семафоров.

Пер­вый семафор служит для блокирования доступа к разделяемой памяти:

0- разрешающий сигнал,

1 - запрещающий сигнал.

Второй семафор служит для сигнализации серверу о том, что клиент начал работу.

Необходимость применения второго семафора обусловлена следующими обстоятельствами: начальное состояние семафора, синхронизирующего работу с памятью, является открытым (0), и вызов сервером операции mem_lock заблокирует обращение к памяти для клиента. Таким образом, сервер должен вызвать операцию mem_lock только после того, как разде­ляемую память заблокирует клиент.

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

Теперь, при вызове сервером операции mem_lock его выполнение будет приостановле­но до освобождения памяти клиентом, который делает это после оконча­ния записи строки "Здравствуй, Мир!".

shmem.h:

#define MAXBUFF 80

#define PERM 0666

/*Структура данных в разделяемой памяти*/ typedef struct mem_msg{

Int segment;

char buff[MAXBUFF];

}Message;

. /*0жидание начала выполнения клиента*/

static struct sembuf proc_wait[l] = {

1, -1, 0 };

/*Уведомление сервера о том, что клиент начал работу*/

static struct sembuf proc_start[1] = {

1, 1, 0 };

/*Блокирование разделяемой памяти*/

static struct sembuf mem_lock[2] = {

0, 0, 0,

0, 1, 0 };

/*Освобождение ресурса*/

static struct sembuf mem_unlock[1] = { 0, -1, 0 };

Сервер:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/sem.h>

#include <sys/shm.h>

#include "shmem.h"

Main()

{

Message *msgptr;

key_t key;