Общие области памяти
В операционных системах Unix и Linux имеется возможность создавать сегменты
памяти, доступные нескольким процессам. При использовании этого средства участки виртуального адресного пространства разных процессов, отображаются на
одни и те же адреса реальной памяти.
При работе с общим сегментом памяти один из процессов должен создать сегмент
разделяемой (общей) памяти, указав требуемый размер сегмента, и получить его
идентификатор. Этот идентификатор затем используется процессом-создателем для
выполнения управляющих операций с разделяемой памятью.
Получив идентификатор разделяемого сегмента памяти (создав сегмент или получив
его идентификатор от другого процесса), процесс должен "присоединить" сегмент.
Операция присоединения возвращает адрес разделяемого сегмента в виртуальном
адресном пространстве процесса. Виртуальный адрес одного и того же сегмента
может быть разным для разных процессов. Далее процессы ведут чтение и запись
данных в сегменте разделяемой памяти, используя для этого те же самые машинные
команды, что и при работе с обычной памятью.
Процесс, закончивший работу с сегментом разделяемой памяти должен "отсоединить"
его, а по окончании использования сегмента всеми процессами он должен быть
уничтожен.
При одновременной работе процессов с общей областью памяти, возможно, требуется
синхронизация их доступа к области. За обеспечение такой синхронизации
полностью отвечает программист, который может использовать для этого алгоритмы,
исключающие конфликты одновременного доступа или системные средства, например,
семафоры.
Системные вызовы Unix/Linux
ОС Unix/Linux механизм разделяемых сегментов памяти обеспечивается четырьмя
системными вызовами: shmget,
shmctl, shmat,
shmdt
.
Системный вызов shmget
создает разделяемый сегмент или возвращает идентификатор уже существующего
сегмента. Этот идентификатор используется при дальнейших операциях с сегментом.
Чтобы получить ID нужен ключ, сформировать который можно с помощью ftok.
Системный вызов shmctl
позволяет выполнять управляющие операции над сегментом: получать информацию о
его состоянии, изменять права доступа к нему, уничтожать сегмент.
Системные вызовы shmat и
shmdt
выполняют присоединение и отсоединение сегмента соответственно.
Разделяемые сегменты памяти в Unix/Linux (как и семафоры) не имеют внешних имен.
При получении идентификатора сегмента процесс пользуется числовым ключом.
Разработчики несвязанных процессов могут договориться об общем значении ключа,
который они будут использовать, но у них нет гарантии в том, что это же
значение ключа не будет использовано кем-то еще. Гарантированно уникальный
сегмент можно создать с использованием ключа IPC_PRIVATE, но такой
ключ не может быть внешним. Поэтому сегменты используются, как правило,
родственными процессами, которые имеют возможность передавать друг другу их
идентификаторы, например, через наследуемые ресурсы или через параметры вызова
дочерней программы.
Внимание!
В процессе отладки программы у Вас могут возникать ситуации, когда программа
будет аварийно заканчиваться или прерываться Вами прежде, чем она уничтожит
созданные ею общие области памяти. Такие области не удаляются в системе
автоматически и могут накапливаться в течение многих дней. Накопление таких
"забытых" общих областей может привести к тому, что будет исчерпан системный
лимит на количество общих областей, и очередной вызов shmget
закончится с ошибкой. Для того, чтобы этого не происходило, регулярно
выполняйте процедуру очистки IPC: /home/metod/rmipc.
Выполняйте эту процедуру также перед каждым выходом из сеанса.
Список созданных Вами общих областей Вы можете увидеть, выполнив команду: ipcs
-m.
|
Пример выполнения приведен здесь.
Справочный материал
Избранные системные вызовы Linux/Unix. Краткое описание.
Cправочник библиотечных функция языка С: часть 1,
часть 2 (кодировка кириллица ibm866).