Interested Article - Разделяемая память
- 2021-08-06
- 1
Разделяемая память ( англ. Shared memory ) является самым быстрым средством обмена данными между процессами .
В других средствах межпроцессового взаимодействия ( IPC ) обмен информацией между процессами проходит через ядро , что приводит к переключению контекста между процессом и ядром, т.е. к потерям производительности .
Техника разделяемой памяти позволяет осуществлять обмен информацией через общий для процессов сегмент памяти без использования системных вызовов ядра. Сегмент разделяемой памяти подключается в свободную часть виртуального адресного пространства процесса . Таким образом, два разных процесса могут иметь разные адреса одной и той же ячейки, подключенной разделяемой памяти.
Краткое описание работы
После создания разделяемого сегмента памяти любой из пользовательских процессов может подсоединить его к своему собственному виртуальному пространству и работать с ним как с обычным сегментом памяти. Недостатком такого обмена информацией является отсутствие каких бы то ни было средств синхронизации, однако для преодоления этого недостатка можно использовать технику семафоров .
Реализация технологии «клиент—сервер»
В схеме обмена данными между двумя процессами — ( клиентом и сервером ), использующими разделяемую память, — должна функционировать группа из двух семафоров. Первый семафор служит для блокирования доступа к разделяемой памяти, его разрешающий сигнал — 1, а запрещающий — 0. Второй семафор служит для сигнализации сервера о том, что клиент начал работу, при этом доступ к разделяемой памяти блокируется, и клиент читает данные из памяти. Теперь при вызове операции сервером его работа будет приостановлена до освобождения памяти клиентом.
Сценарий использования разделяемой памяти
- Сервер получает доступ к разделяемой памяти, используя семафор.
- Сервер производит запись данных в разделяемую память.
- После завершения записи данных сервер освобождает доступ к разделяемой памяти с помощью семафора.
- Клиент получает доступ к разделяемой памяти, запирая доступ к этой памяти для других процессов с помощью семафора.
- Клиент производит чтение данных из разделяемой памяти, а затем освобождает доступ к памяти с помощью семафора.
Программная реализация
В программном обеспечении разделяемой памятью называют:
- Метод межпроцессного взаимодействия (IPC), то есть способ обмена данными между программами, работающими одновременно. Один процесс создаёт область в оперативной памяти, которая может быть доступна для других процессов.
- Метод экономии памяти, путём прямого обращения к тем исходным данным, которые при обычном подходе являются отдельными копиями исходных данных, вместо отображения виртуальной памяти или описанного метода . Такой подход обычно используется для разделяемых библиотек и для XIP .
Поскольку оба процесса могут получить доступ к общей области памяти как к обычной памяти, это очень быстрый способ связи (в отличие от других механизмов IPC, таких как именованные каналы , UNIX-сокеты или CORBA ). С другой стороны, такой способ менее гибкий, например, обменивающиеся процессы должны быть запущены на одной машине (из перечисленных методов IPC только сетевые сокеты, не путать с сокетами домена UNIX, могут вести обмен данными через сеть), и необходимо быть внимательным, чтобы избежать проблем при использовании разделяемой памяти на разных ядрах процессора и аппаратной архитектуре без когерентного кэша .
Обмен данными через разделяемую память используется, например, для передачи изображений между приложением и X-сервером на Unix-системах или внутри объекта IStream возвращаемого CoMarshalInterThreadInterfaceInStream в библиотеке COM под Windows.
Динамические библиотеки , как правило, загружаются в память один раз и отображены на несколько процессов, и только страницы, которые специфичны для отдельного процесса (поскольку отличаются некоторые идентификаторы) дублируются, как правило, с помощью механизма, известного как копирование-при-записи , который при попытке записи в разделяемую память незаметно для вызывающего запись процесса копирует страницы памяти, а затем записывает данные в эту копию.
В UNIX-подобных операционных системах
POSIX
предоставляет стандартизированное
API
для работы с разделяемой памятью —
POSIX Shared Memory
. Одной из ключевых особенностей операционных систем семейства
UNIX
является механизм копирования процессов (системный вызов
fork()
), который позволяет создавать анонимные участки разделяемой памяти перед копированием процесса и наследовать их процессами-потомками. После копирования процесса разделяемая память будет доступна как родительскому, так и дочернему процессу.
Существует два разных подхода к подключению и использованию разделяемой памяти:
-
в стиле
UNIX System V
, используя функции расширения
POSIX:XSI
(часть стандарта
POSIX.1-2001
)
shmget
,shmctl
,shmat
иshmdt
; -
через функции
POSIX
shm_open
,shm_unlink
,ftruncate
иmmap
(стандарт POSIX.1-2001 ) .
Разделяемая память в стиле UNIX System V
UNIX System V предоставляет набор функций языка C, позволяющий работать с разделяемой памятью :
-
shmget
— создание сегмента разделяемой памяти с привязкой к целочисленному идентификатору, либо анонимного сегмента разделяемой памяти (при указании вместо идентификатора значения IPC_PRIVATE) ; -
shmctl
— установка параметров сегмента памяти ; -
shmat
— подключение сегмента к адресному пространству процесса ; -
shmdt
— отключение сегмента от адресного пространства процесса .
Именованная разделяемая память подразумевает ассоциацию с каждым участком памяти уникального числового ключа в рамках операционной системы, по которому в дальнейшем можно подключить разделяемую память в другом процессе.
Разделяемая память POSIX
POSIX позволяет связать с объектом разделяемой памяти файловый дескриптор , что является более унифицированным механизмом, чем механизм UNIX System V. Для работы с памятью могут быть использованы следующие функции языка C:
-
shm_open
— создание или подключение объекта разделяемой памяти POSIX по его имени ; -
shm_unlink
— удаление объекта разделяемой памяти по его имени (при этом сегмент разделяемой памяти будет существовать, пока не будет отключен от всех процессов) ; -
ftruncate
— задаёт или изменяет размер разделяемой памяти (или отображённого в память файла) ; -
mmap
— подключает существующий или создаёт анонимный сегмент разделяемой памяти к адресному пространству процесса .
В операционных системах семейства Windows
В операционной системе
Windows
для создания разделяемой памяти используются функции
CreateFileMapping
и
MapViewOfFile
из
MSDN
.
Поддержка в языках программирования
Некоторые библиотеки языка
C++
предлагают доступ к работе с разделяемой памятью в
кроссплатформенном
виде. Например, библиотека
Boost
предоставляет
класс
boost::interprocess::shared_memory_object
для
POSIX-совместимых
операционных систем, а библиотека
Qt
предоставляет класс
QSharedMemory
,
унифицирующий доступ к разделяемой памяти для разных операционных систем с некоторыми ограничениями
.
В
Java 7
под операционной системой
GNU/Linux
разделяемая память может быть реализована отображением файла из каталога
/dev/shm/
(либо
/run/shm/
, в зависимости от дистрибутива) в память
с помощью метода
map
класса
java.nio.MappedByteBuffer
.
Поддержка разделяемой памяти осуществлена во многих других языках программирования . Так, PHP предоставляет API для создания разделяемой памяти, чьи функции схожи с функциями POSIX .
См. также
Примечания
- Колисниченко Денис Николаевич. . — БХВ-Петербург, 2012-01-01. — 430 с. — ISBN 9785977507479 . 23 июля 2016 года.
- Hyok-Sung Choi, Hee-Chul Yun. (англ.) // Samsung Electronics : Технический отчёт. — 2004. 6 марта 2016 года.
- ↑ . pubs.opengroup.org. Дата обращения: 3 января 2016. 6 декабря 2015 года.
- ↑ . pubs.opengroup.org. Дата обращения: 3 января 2016. 30 декабря 2015 года.
- . pubs.opengroup.org. Дата обращения: 3 января 2016. 8 января 2016 года.
- ↑ . pubs.opengroup.org. Дата обращения: 3 января 2016. 21 ноября 2015 года.
- Kay A. Robbins. . — Prentice Hall PTR, 2003. — С. 512. 22 сентября 2014 года.
- ↑ . pubs.opengroup.org. Дата обращения: 3 января 2016. 5 марта 2016 года.
- . pubs.opengroup.org. Дата обращения: 3 января 2016. 7 декабря 2015 года.
- . pubs.opengroup.org. Дата обращения: 3 января 2016. 12 декабря 2015 года.
- . pubs.opengroup.org. Дата обращения: 3 января 2016. 9 ноября 2015 года.
- . pubs.opengroup.org. Дата обращения: 3 января 2016. 1 февраля 2016 года.
- . Дата обращения: 26 июня 2014. 5 июня 2014 года.
- . www.boost.org. Дата обращения: 4 января 2016. 29 декабря 2015 года.
- . doc.qt.io. Дата обращения: 4 января 2016. 7 декабря 2015 года.
- . man7.org. Дата обращения: 4 января 2016. 4 января 2016 года.
- . docs.oracle.com. Дата обращения: 4 января 2016. 15 января 2016 года.
- . Дата обращения: 26 июня 2014. 25 июня 2014 года.
- 2021-08-06
- 1