3. Мы говорили, что при вызове mmap с флагом MAP_SHARED для синхронизации содержимого файла и памяти используются алгоритмы ядра для работы с виртуальной памятью. Прочитайте страницу документации, относящуюся к /dev/zero, чтобы узнать, что происходит, когда ядро записывает изменения обратно в этот файл.
4. Измените программу в листинге 12.2, указав MAP_PRIVATE вместо MAP_SHARED. Проверьте, что результаты будут такими же, как и при выполнении программы из листинга 12.1. Что будет содержаться в файле, отображенном в память?
5. В разделе 6.9 мы отметили, что единственным способом использовать select с очередью сообщений System V является создание неименованной области памяти, порождение процесса и блокирование его в вызове msgrcv, причем сообщение должно считываться в разделяемую память. Родительский процесс также создает два канала, один из которых используется для уведомления его о том, что сообщение помещено в разделяемую память, а другой — для уведомления дочернего процесса о возможности помещения нового сообщения в эту память. Тогда родительский процесс может вызвать select для открытого на чтение конца канала вместе с любыми другими дескрипторами. Напишите программу, реализующую этот алгоритм. Для выделения области неименованной разделяемой памяти используйте функцию my_shm (листинг А.31). Для создания очереди сообщений и помещения в нее записей используйте программы msgcreate и msgsnd из раздела 6.6. Родительский процесс должен просто выводить размер и тип всех считываемых дочерним процессом сообщений.
ГЛАВА 13
Разделяемая память Posix
13.1. Введение
В предыдущей главе рассматривались общие вопросы, связанные с разделяемой памятью, и детально разбиралась функция mmap. Были приведены примеры, в которых вызов mmap использовался для создания области памяти, совместно используемой родительским и дочерним процессами. В этих примерах использовалось:
■ отображение файлов в память (листинг 12.2);
■ неименованное отображение памяти в системе 4.4BSD (листинг 12.4);
■ неименованное отображение файла /dev/zero (листинг 12.5).
Теперь мы можем расширить понятие разделяемой памяти, включив в него память, совместно используемую неродственными процессами. Стандарт Posix.1 предоставляет два механизма совместного использования областей памяти для неродственных процессов:
1. Отображение файлов в память: файл открывается вызовом open, а его дескриптор используется при вызове mmap для отображения содержимого файла в адресное пространство процесса. Этот метод был описан в главе 12, и его использование было проиллюстрировано на примере родственных процессов. Однако он позволяет реализовать совместное использование памяти и для неродственных процессов.
2. Объекты разделяемой памяти: функция shm_open открывает объект IPC с именем стандарта Posix (например, полным именем объекта файловой системы), возвращая дескриптор, который может быть использован для отображения в адресное пространство процесса вызовом mmap. Данный метод будет описан в этой главе.
Оба метода требуют вызова mmap. Отличие состоит в методе получения дескриптора, являющегося аргументом mmap: в первом случае он возвращается функцией open, а во втором — shm_open. Мы показываем это на рис. 13.1. Стандарт Posix называет
13.2. Функции shm_open и shm_unlink
Процесс получения доступа к объекту разделяемой памяти Posix выполняется в два этапа:
1. Вызов shm_open с именем IPC в качестве аргумента позволяет либо создать новый объект разделяемой памяти, либо открыть существующий.
Рис. 13.1. Объекты памяти Posix: отображаемые в память файлы и объекты разделяемой памяти
2. Вызов mmap позволяет отобразить разделяемую память в адресное пространство вызвавшего процесса.
Аргумент