Чтение онлайн

на главную - закладки

Жанры

Программирование для Linux. Профессиональный подход

Самьюэл Алекс

Шрифт:

5.1.2. Модель памяти

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

Для того чтобы понять принципы выделения и подключения сегментов памяти, необходимо разобраться в модели памяти Linux. В Linux виртуальная память (ВП) каждого процесса разбита на страницы. Все процессы хранят таблицу соответствий между своими адресами памяти и страницами ВП, содержащими реальные данные. Несмотря на то что за каждым процессом закреплены

свои адреса, разным процессам разрешается ссылаться на одни и те же страницы. Это и есть совместное использование памяти.

При выделении совместно используемого сегмента памяти создаются страницы ВП. Это действие должно выполняться только одни раз, так как все остальные процессы будут обращаться к этому же сегменту. Если запрашивается выделение существующего сегмента, новые страницы не создаются; вместо этого возвращается идентификатор существующих страниц. Чтобы сделать сегмент общедоступным, процесс подключает его, при этом создаются адресные ссылки на страницы сегмента. По окончании работы с сегментом адресные ссылки удаляются. Когда все процессы завершили работу с сегментом, один (и только один) из них должен освободить страницы виртуальной памяти.

Размер совместно используемого сегмента кратен размеру страницы ВП. В Linux последняя величина обычно равна 4 Кбайт, но никогда не помешает это проверить с помощью функции

getpagesize
.

5.1.3. Выделение сегментов памяти

Процесс выделяет сегмент памяти с помощью функции

shmget
. Первым аргументом функции является целочисленный ключ, идентифицирующий создаваемый сегмент. Если несвязанные процессы хотят получить доступ к одному и тому же сегменту, они должны указать одинаковый ключ. К сожалению, ничто не мешает посторонним процессам выбрать тот же самый ключ сегмента, а это приведет к системному конфликту. Указание специальной константы
IPC_PRIVATE
в качестве ключа позволяет гарантировать, что будет создан совершенно новый сегмент.

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

Третий параметр содержит набор битовых флагов. Перечислим наиболее важные из них.

IPC_CREAT
. Указывает на то, что создается новый сегмент, которому присваивается заданный ключ.

■ 

IPC_EXCL
. Всегда используется совместно с флагом
IPC_CREAT
и заставляет функцию
shmget
выдать ошибку в случае, когда сегмент с указанным ключом уже существует. Если флаг не указан и возникает описанная ситуация, функция
shmget
возвращает идентификатор существующего сегмента, не создавая новый сегмент.

■ Флаги режима. В эту группу входят 9 флагов, задающих права доступа к сегменту для владельца, группы и остальных пользователей. Биты выполнения игнорируются. Проще всего задавать права доступа с помощью констант, определенных в файле

<sys/stat.h>
(они описаны на
man
– странице функции
stat
). [15] Например, флаги
S_IRUSR
и
S_IWUSR
предоставляют право чтения и записи владельцу сегмента, а флаги
S_IROTH
и
S_IWOTH
предоставляют аналогичные права остальным пользователям.

15

Эти

же константы используются при работе с файлами. Они описываются в разделе 10.3. "Права доступа к файлам".

В следующем фрагменте программы функция

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
отключают сегменты, но не освобождают их.

Поделиться:
Популярные книги

Белые погоны

Лисина Александра
3. Гибрид
Фантастика:
фэнтези
попаданцы
технофэнтези
аниме
5.00
рейтинг книги
Белые погоны

Черный дембель. Часть 1

Федин Андрей Анатольевич
1. Черный дембель
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Черный дембель. Часть 1

Лишняя дочь

Nata Zzika
Любовные романы:
любовно-фантастические романы
8.22
рейтинг книги
Лишняя дочь

Темный Лекарь 5

Токсик Саша
5. Темный Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Темный Лекарь 5

Последний из рода Демидовых

Ветров Борис
Фантастика:
детективная фантастика
попаданцы
аниме
5.00
рейтинг книги
Последний из рода Демидовых

Чиновникъ Особых поручений

Кулаков Алексей Иванович
6. Александр Агренев
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Чиновникъ Особых поручений

Попаданка в академии драконов 4

Свадьбина Любовь
4. Попаданка в академии драконов
Любовные романы:
любовно-фантастические романы
7.47
рейтинг книги
Попаданка в академии драконов 4

Боги, пиво и дурак. Том 6

Горина Юлия Николаевна
6. Боги, пиво и дурак
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Боги, пиво и дурак. Том 6

Курсант: Назад в СССР 10

Дамиров Рафаэль
10. Курсант
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Курсант: Назад в СССР 10

Сделай это со мной снова

Рам Янка
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Сделай это со мной снова

Болотник 2

Панченко Андрей Алексеевич
2. Болотник
Фантастика:
попаданцы
альтернативная история
6.25
рейтинг книги
Болотник 2

Камень Книга двенадцатая

Минин Станислав
12. Камень
Фантастика:
боевая фантастика
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Камень Книга двенадцатая

Небо для Беса

Рам Янка
3. Самбисты
Любовные романы:
современные любовные романы
5.25
рейтинг книги
Небо для Беса

Надуй щеки! Том 4

Вишневский Сергей Викторович
4. Чеболь за партой
Фантастика:
попаданцы
уся
дорама
5.00
рейтинг книги
Надуй щеки! Том 4