Руководство программиста для Linux


Разделяемая память - часть 2


Размеры сегмента (в байтах).

shm_atime

Время последней привязки к сегменту.

shm_dtime

Время последней отвязки процесса от сегмента.

shm_ctime

Время последнего изменения этой структуры (изменение mode и т.п.).

shm_cpid

PID создавшего процесса.

shm_lpid

PID последнего процесса обратившегося к сегменту.

shm_nattch

Число процессов, привязанных к сегменту на данный момент.

Системный вызов shmget()

Чтобы создать новый разделяемый сегмент памяти или получить доступ к уже существующему, используется системный вызов shmget(). SYSTEM CALL: shmget(); PROTOTYPE: int shmget ( key_t key, int size, int shmflg ); RETURNS: идентификатор разделяемого сегмента памяти в случае успеха -1 в случае ошибки: errno = EINVAL (Ошибочно заданы размеры сегмента) EEXIST (Сегмент существует, нельзя создать) EIDRM (Сегмент отмечен для удаления, или был удален) ENOENT (Сегмент не существует) EACCESS (Доступ отклонен) ENOMEM (Недостаточно памяти для создания сегмента) NOTES:

Этот новый вызов должен выглядеть для вас почти как старые новости. Он поразительно похож на соответствующие вызовы get для очередей сообщений и множеств семафоров.

Первый аргумент для shmget() - это значение ключа (в нашем случае возвращен посредством вызова ftok()-а). Это значение ключа затем сравнивается с существующими значениями, которые находятся внутри ядра для других разделяемых сегментов памяти. В этом отношении операция открытия или получения доступа зависит от содержания аргумента shmflg.

IPC_CREAT

Создает сегмент, если он еще не существует в ядре.

IPC_EXCL

При использовании совместно с IPC_CREAT приводит к ошибке, если сегмент уже существует.

Если используется один IPC_CREAT, то shmget() возвращает либо идентификатор для вновь созданного сегмента, либо идентификатор для сегмента, который уже существует с тем же значением ключа. Если вместе с IPC_CREAT используется IPC_EXCL, тогда либо создается новый сегмент, либо, если сегмент уже существует, вызов "проваливается" с -1. IPC_EXCL сам по себе бесполезен, но если он комбинируется с IPC_CREAT, то может быть использован как способ получения гарантии, что нет уже существующих сегментов, открытых для доступа.

Повторимся, (необязательный) восьмеричный доступ может быть объеденен по ИЛИ в маску доступа.

Давайте создадим функцию-переходник для обнаружения или создания разделяемого сегмента памяти: int open_segment( key_t keyval, int segsize ) { int shmid; if((shmid = shmget( keyval, segsize, IPC_CREAT | 0660 )) == -1) { return(-1); } return(shmid); }




Начало  Назад  Вперед