Процесс выделяет сегмент памяти с помощью функции shmget()
IPC_PRIVATE
в качестве ключа позволяет гарантировать, что будет создан совершенно новый сегмент.Во втором аргументе функции задается размер сегмента в байтах. Это значение округляется, чтобы быть кратным размеру страницы ВП.
Третий параметр содержит набор битовых флагов. Перечислим наиболее важные из них.
■ IPC_CREAT
■ IPC_EXCL
IPC_CREAT
и заставляет функцию shmget()
выдать ошибку в случае, когда сегмент с указанным ключом уже существует. Если флаг не указан и возникает описанная ситуация, функция shmget()
возвращает идентификатор существующего сегмента, не создавая новый сегмент.■
(они описаны на man
-странице функции stat()
).[15] Например, флаги S_IRUSR
и S_IWUSR
предоставляют право чтения и записи владельцу сегмента, а флаги S_IROTH
и S_IWOTH
предоставляют аналогичные права остальным пользователям.В следующем фрагменте программы функция shmget()
shm_key
уже зарегистрировано в системе), доступный для чтения/записи только его владельцу:int segment_id = shmget(shm_key, getpagesize(),
IPC_CREAT | S_IRUSR | S_IWUSR);
В случае успешного завершения функция возвращает идентификатор сегмента. Если сегмент уже существует, проверяются нрава доступа к нему.
5.1.4. Подключение и отключение сегментов
Чтобы сделать сегмент памяти общедоступным, процесс должен подключить его с помощью функции shmat()
shmget()
. Второй аргумент — это указатель, определяющий, где в адресном пространстве процесса необходимо создать привязку на совместно используемую область памяти. Если задать значение NULL
, ОС Linux выберет первый доступный адрес. Третий аргумент может содержать следующие флаги.■ SHM_RND
■ SHM_RDONLY
В случае успешного завершения функция возвращает адрес подключенного сегмента. Дочерний процесс, созданный функцией fork()
По завершении работы с сегментом его необходимо отключить с помощью функции shmdt()
shmat()
. Если текущий процесс был последним, кто ссылался на сегмент, сегмент удаляется из памяти. Функции exit()
и exec()
автоматически отключают сегменты.5.1.5. Контроль и освобождение совместно используемой памяти
Функция shmctl()
Чтобы получить информацию о сегменте, укажите в качестве второго параметра константу IPC_STAT
shmid_ds
.Чтобы удалить сегмент, передайте во втором параметре константу IPC_RMID
NULL
. Сегмент удаляется, когда последний подключивший его процесс отключает сегмент.Каждый совместно используемый сегмент должен явно освобождаться с помощью функции shmctl()
exit()
и exec()
отключают сегменты, но не освобождают их.Описание других операций, выполняемых над совместно используемыми сегментами памяти, можно найти на man
shmctl()
.5.1.6. Пример программы
Программа, приведенная в листинге 5.1, иллюстрирует методику совместного использования памяти.
#include
#include
#include
int main() {
int segment_id;