Разделяемая память (англ. Shared memory) является самым быстрым средством обмена данными между процессами[1].
В других средствах межпроцессового взаимодействия (IPC) обмен информацией между процессами проходит через ядро, что приводит к переключению контекста между процессом и ядром, т.е. к потерям производительности[2].
Техника разделяемой памяти позволяет осуществлять обмен информацией через общий для процессов сегмент памяти без использования системных вызовов ядра. Сегмент разделяемой памяти подключается в свободную часть виртуального адресного пространства процесса[3]. Таким образом, два разных процесса могут иметь разные адреса одной и той же ячейки подключенной разделяемой памяти.
После создания разделяемого сегмента памяти любой из пользовательских процессов может подсоединить его к своему собственному виртуальному пространству и работать с ним, как с обычным сегментом памяти. Недостатком такого обмена информацией является отсутствие каких бы то ни было средств синхронизации, однако для преодоления этого недостатка можно использовать технику семафоров.
В схеме обмена данными между двумя процессами — (клиентом и сервером), использующими разделяемую память, — должна функционировать группа из двух семафоров. Первый семафор служит для блокирования доступа к разделяемой памяти, его разрешающий сигнал — 1, а запрещающий — 0. Второй семафор служит для сигнализации сервера о том, что клиент начал работу, при этом доступ к разделяемой памяти блокируется, и клиент читает данные из памяти. Теперь при вызове операции сервером его работа будет приостановлена до освобождения памяти клиентом.
В программном обеспечении разделяемой памятью называют:
Поскольку оба процесса могут получить доступ к общей области памяти как к обычной памяти, это очень быстрый способ связи (в отличие от других механизмов IPC, таких как именованные каналы, UNIX-сокеты или CORBA). С другой стороны, такой способ менее гибкий, например, обменивающиеся процессы должны быть запущены на одной машине (из перечисленных методов IPC только сетевые сокеты, не путать с сокетами домена UNIX, могут вести обмен данными через сеть), и необходимо быть внимательным, чтобы избежать проблем при использовании разделяемой памяти на разных ядрах процессора и аппаратной архитектуре без когерентного кэша.
Обмен данными через разделяемую память используется, например, для передачи изображений между приложением и X-сервером на Unix системах, или внутри объекта IStream возвращаемого CoMarshalInterThreadInterfaceInStream в библиотеке COM под Windows.
Динамические библиотеки, как правило, загружаются в память один раз и отображены на несколько процессов, и только страницы, которые специфичны для отдельного процесса (поскольку отличаются некоторые идентификаторы) дублируются, как правило, с помощью механизма, известного как копирование-при-записи, который при попытке записи в разделяемую память незаметно для вызывающего запись процесса копирует страницы памяти, а затем записывает данные в эту копию.
POSIX предоставляет стандартизированное API для работы с разделяемой памятью — POSIX Shared Memory. Одной из ключевых особенностей операционных систем семейства UNIX является механизм копирования процессов (системный вызов fork()
), который позволяет создавать анонимные участки разделяемой памяти перед копированием процесса и наследовать их процессами-потомками. После копирования процесса разделяемая память будет доступна как родительскому, так и дочернему процессу.[3][4]
Существует два разных подхода к подключению и использованию разделяемой памяти:
shmget
, shmctl
, shmat
и shmdt
[5];shm_open
, shm_unlink
, ftruncate
и mmap
(стандарт POSIX.1-2001)[6].UNIX System V предоставляет набор функций языка C, позволяющий работать с разделяемой памятью[7]:
shmget
— создание сегмента разделяемой памяти с привязкой к целочисленному идентификатору, либо анонимного сегмента разделяемой памяти (при указании вместо идентификатора значения IPC_PRIVATE)[8];shmctl
— установка параметров сегмента памяти[9];shmat
— подключение сегмента к адресному пространству процесса[4];shmdt
— отключение сегмента от адресного пространства процесса[10].Именованная разделяемая память подразумевает ассоциацию с каждым участком памяти уникального числового ключа в рамках операционной системы, по которому в дальнейшем можно подключить разделяемую память в другом процессе.[8]
POSIX позволяет связать с объектом разделяемой памяти файловый дескриптор, что является более унифицированным механизмом, чем механизм UNIX System V. Для работы с памятью могут быть использованы следующие функции языка C:
shm_open
— создание или подключение объекта разделяемой памяти POSIX по его имени[6];shm_unlink
— удаление объекта разделяемой памяти по его имени (при этом сегмент разделяемой памяти будет существовать, пока не будет отключен от всех процессов)[11];ftruncate
— задаёт или изменяет размер разделяемой памяти (или отображённого в память файла)[12];mmap
— подключает существующий или создаёт анонимный сегмент разделяемой памяти к адресному пространству процесса[3].В операционной системе Windows для создания разделяемой памяти используется функция CreateSharedMemory
[13] из пакета Win32-SDK. C другой стороны, возможно использование функций CreateFileMapping
и MapViewOfFile
[14] из MSDN.
Некоторые библиотеки языка C++ предлагают доступ к работе с разделяемой памятью в кроссплатформенном виде. Например, библиотека Boost предоставляет класс boost::interprocess::shared_memory_object
[15] для POSIX-совместимых операционных систем, а библиотека Qt предоставляет класс QSharedMemory
, унифицирующий доступ к разделяемой памяти для разных операционных систем с некоторыми ограничениями[16].
В Java 7 под операционной системой GNU/Linux разделяемая память может быть реализована отображением файла из каталога /dev/shm/
(либо /run/shm/
, в зависимости от дистрибутива) в память[17] с помощью метода map
класса java.nio.MappedByteBuffer
[18].
Поддержка разделяемой памяти осуществлена во многих других языках программирования. Так, PHP предоставляет API[19] для создания разделяемой памяти, чьи функции схожи с функциями POSIX.
Для улучшения этой статьи желательно: |
Данная страница на сайте WikiSort.ru содержит текст со страницы сайта "Википедия".
Если Вы хотите её отредактировать, то можете сделать это на странице редактирования в Википедии.
Если сделанные Вами правки не будут кем-нибудь удалены, то через несколько дней они появятся на сайте WikiSort.ru .