Friday, May 18th

Last update12:13:00 PM GMT

Вы находитесь на: FreeBSD Управление памятью Разделяемая память

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

Традиционно адресное пространство каждого процесса было полностью изолировано от адресного пространства всех других процессов, работающих в системе. Единственным исключением было разделение с доступом только для чтения кода программы. Все межпроцессное взаимодействие осуществлялось посредством хорошо определенных путей, которые проходили через ядро: каналы, сокеты, файлы и специальные устройства. Преимуществом этого изолированного подхода является то, что независимо от каких бы то ни было разрушительных действий процесса в его собственном адресном пространстве он не мог повлиять на адресное пространство любых других работающих в системе процессов. Каждый процесс может строго контролировать отправку и получение данных; он может также точно определять места внутри своего адресного пространства, которые читаются или записываются. Недостатком этого подхода является то, что все межпроцессные взаимодействия требуют по крайней мере двух системных вызовов: одного для отправляющего процесса и одного для получающего процесса. Для больших объемов межпроцессного взаимодействия, особенно при обмене небольшими пакетами данных, в стоимости коммуникации преобладают издержки системных вызовов.

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

В некоторых вариантах UNIX есть механизм основанного на ядре семафора для предоставления необходимого упорядочивания доступа к разделяемой памяти. Однако как получение, так и установка таких семафоров требуют системных вызовов. Издержки по использованию таких семафоров сравнимы с издержками использования традиционных методов межпроцессного взаимодействия. К сожалению, эти семафоры имеют все сложности разделяемой памяти, давая к тому же лишь незначительную часть преимуществ в скорости. Главной причиной для введения сложности разделяемой памяти является соразмерный выигрыш в скорости. Если должен быть получен этот выигрыш, большая часть потребностей в блокировке структур данных должна осуществляться в самом сегменте разделяемой памяти. Основанные на ядре семафоры должны использоваться лишь в тех редких случаях, когда имеется соперничество за блокировку и один процесс должен ждать. Поэтому современные интерфейсы, такие, как POSIX Pthreads, спроектированы таким образом, что семафоры могут быть расположены в области разделяемой памяти. В общем случае установка или освобождение неоспариваемого семафора могут осуществляться процессом пользователя без вызова ядра. Имеются два случая, когда процесс должен сделать системный вызов. Если процесс пытается установить уже заблокированный семафор, он должен вызвать ядро, чтобы заблокироваться, пока семафор не станет доступным. Этот системный вызов мало влияет на производительность, поскольку блокировка оспаривается, поэтому невозможно продолжать работу и в любом случае должно быть вызвано ядро для переключения контекста. Если процесс освобождает семафор, который хочет получить другой процесс, он должен вызвать ядро, чтобы пробудить этот процесс. Поскольку большинство блокировок не оспариваются, приложения могут работать с полной скоростью без вмешательства ядра.


Похожие:
Еще по теме:
Советуем прочитать:

Сейчас 50 гостей онлайн