Программирование для Linux. Профессиональный подход
Шрифт:
5.1.2. Модель памяти
При совместном использовании сегмента памяти один процесс должен сначала выделить память. Затем все остальные процессы, которые хотят получить доступ к ней, должны подключить сегмент. По окончании работы с сегментом каждый процесс отключает его. Последний процесс освобождает память.
Для того чтобы понять принципы выделения и подключения сегментов памяти, необходимо разобраться в модели памяти Linux. В Linux виртуальная память (ВП) каждого процесса разбита на страницы. Все процессы хранят таблицу соответствий между своими адресами памяти и страницами ВП, содержащими реальные данные. Несмотря на то что за каждым процессом закреплены свои адреса, разным процессам разрешается ссылаться на одни и те же страницы. Это и есть совместное использование памяти.
При выделении совместно используемого сегмента памяти создаются страницы ВП. Это действие должно выполняться только одни раз, так как все остальные процессы будут обращаться к этому же сегменту. Если запрашивается выделение существующего сегмента, новые страницы не создаются; вместо этого возвращается идентификатор существующих страниц. Чтобы сделать сегмент общедоступным, процесс подключает его, при этом создаются адресные ссылки на страницы сегмента. По окончании работы с сегментом адресные ссылки удаляются. Когда все процессы завершили работу с сегментом, один (и только один) из них должен освободить страницы виртуальной памяти.
Размер совместно используемого сегмента кратен размеру страницы ВП. В Linux последняя величина обычно равна 4 Кбайт, но никогда не помешает это проверить с помощью функции
5.1.3. Выделение сегментов памяти
Процесс выделяет сегмент памяти с помощью функции
Во втором аргументе функции задается размер сегмента в байтах. Это значение округляется, чтобы быть кратным размеру страницы ВП.
Третий параметр содержит набор битовых флагов. Перечислим наиболее важные из них.
■
■
■ Флаги режима. В эту группу входят 9 флагов, задающих права доступа к сегменту для владельца, группы и остальных пользователей. Биты выполнения игнорируются. Проще всего задавать права доступа с помощью констант, определенных в файле
15
Эти же константы используются при работе с файлами. Они описываются в разделе 10.3. "Права доступа к файлам".
В следующем фрагменте программы функция
В случае успешного завершения функция возвращает идентификатор сегмента. Если сегмент уже существует, проверяются нрава доступа к нему.
5.1.4. Подключение и отключение сегментов
Чтобы сделать сегмент памяти общедоступным, процесс должен подключить его с помощью функции
■
■
В случае успешного завершения функция возвращает адрес подключенного сегмента. Дочерний процесс, созданный функцией
По завершении работы с сегментом его необходимо отключить с помощью функции
5.1.5. Контроль и освобождение совместно используемой памяти
Функция
Чтобы получить информацию о сегменте, укажите в качестве второго параметра константу
Чтобы удалить сегмент, передайте во втором параметре константу
Каждый совместно используемый сегмент должен явно освобождаться с помощью функции