Разделяемая память

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск
Наглядное представление разделяемой памяти

Разделяемую память (англ. Shared memory) применяют для того, чтобы увеличить скорость прохождения данных между процессами. В обычной ситуации обмен информацией между процессами проходит через ядро. Техника разделяемой памяти позволяет осуществить обмен информацией не через ядро, а используя некоторую часть виртуального адресного пространства, куда помещаются и откуда считываются данные.

Краткое описание работы[править | править вики-текст]

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

Реализация технологии «клиент—сервер»[править | править вики-текст]

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

Сценарий использования разделяемой памяти[править | править вики-текст]

  1. Сервер получает доступ к разделяемой памяти, используя семафор;
  2. Сервер производит запись данных в разделяемую память;
  3. После завершения записи данных сервер освобождает доступ к разделяемой памяти с помощью семафора;
  4. Клиент получает доступ к разделяемой памяти, запирая доступ к этой памяти для других процессов с помощью семафора;
  5. Клиент производит чтение данных из разделяемой памяти, а затем освобождает доступ к памяти с помощью семафора.

Программная реализация[править | править вики-текст]

В программном обеспечении разделяемой памятью называют:

  • Метод межпроцессного взаимодействия (IPC), т.е. способ обмена данными между программами, работающими одновременно. Один процесс создаёт область в оперативной памяти, которая может быть доступна для других процессов.
  • Метод экономии памяти, путем прямого обращения к тем исходным данным, которые при обычном подходе являются отдельными копиями исходных данных, вместо отображения виртуальной памяти или описанного метода . Такой подход обычно используется для разделяемых библиотек и для XIP.

Поскольку оба процесса могут получить доступ к общей области памяти как к обычной памяти, это очень быстрый способ связи (в отличие от других механизмов IPC, таких как именованные каналы, Unix сокеты или CORBA). С другой стороны, такой способ менее гибкий, например, обменивающиеся процессы должны быть запущены на одной машине (из перечисленных методов IPC только сетевые сокеты (не путать с Unix сокетами) могут вести обмен данными через сеть), и необходимо быть внимательным, чтобы избежать проблем, при использование разделяемой памяти на разных ядрах процессора и аппаратной архитектуре без когерентного кэша.

Обмен данными через разделяемую память используется, например, для передачи изображений между приложением и X-сервером на Unix системах, или внутри объекта IStream возвращаемого CoMarshalInterThreadInterfaceInStream в библиотеке COM под Windows.

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

В UNIX-подобных операционных системах[править | править вики-текст]

POSIX предоставляет стандартизированное API для работы с разделяемой памятью - POSIX Shared Memory. Взаимодействие реализуется через функцию shm_open, описанную в файле sys/mman.h[1].

Межпроцессное взаимодействие в POSIX (часть расширения POSIX:XSI) включает в себя следующие функции[2]:

  • shmget — создание сегмента разделяемой памяти
  • shmctl — установка параметров
  • shmat — подсоединение сегмента памяти
  • shmdt — отсоединение сегмента

В других операционных системах[править | править вики-текст]

В операционной системе Windows для создания разделяемой памяти используется функция CreateSharedMemory[3] из пакета Win32-SDK. C другой стороны, возможно использование функций CreateFileMapping и MapViewOfFile[4] из MSDN.

Некоторые библиотеки языка C++ так же могут предоставить доступ к функциям разделяемой памяти в определенном виде. Например, библиотека Boost, содержащая Boost.Interprocess C++ Library[5], Qt, содержащее QSharedMemory class[6].

Аналогично, поддержка разделяемой памяти осуществлена во многих языках программирования. Так, PHP предоставляет API[7] для создания разделяемой памяти, чьи функции схожи с функциями POSIX.

См. также[править | править вики-текст]

Проблема ABA

Примечания[править | править вики-текст]

  1. Documentation of shm_open.
  2. Kay A. Robbins UNIX systems programming: communication, concurrency, and threads. — Prentice Hall PTR, 2003. — С. 512.
  3. Функция CreateSharedMemory.
  4. Creating Named Shared Memory.
  5. Boost.Interprocess C++ Library.
  6. QSharedMemory Class Reference.
  7. Shared Memory Functions in PHP-API.