Общая память между 2 процессами (приложениями) - PullRequest
16 голосов
/ 05 января 2010

Я не могу найти полезного ответа на этот вопрос, хотя его несколько раз задавали по-другому.

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

Возможно ли это в .NET? Как?

Спасибо

Ответы [ 5 ]

29 голосов
/ 05 января 2010

Прямо сейчас .NET не поддерживает разделы (также называемые Memory Mapped Files). Это скоро, версия 4.0 имеет пространство имен System.IO.MemoryMappedFiles. Есть веская причина, по которой это заняло так много времени, а также причина, по которой вы не будете довольны этим дополнением. Использование указателей является обязательным в MMF, общая память предоставляется по определенному адресу. Чтобы поделиться значением, вам нужно записать его по определенному адресу.

Однако указатели принципиально несовместимы с моделью управляемой памяти. Объекты создаются в куче мусора, сборщик перемещает их по мере необходимости, чтобы сохранить кучу компактной. В управляемом языке у вас есть ссылка на такой объект, также известный как «дескриптор отслеживания». Эквивалент C / C ++ является указателем, но он с колоколами, сборщик мусора всегда может найти его и обновить его значение. CLR поддерживает понятие «закрепление», оно преобразует ссылку на указатель. Он реализует это, помечая объект как неподвижный. Это, однако, не помогает реализовать разделяемую память через MMF, объект закрепляется в куче GC вместо адреса виртуальной памяти, где находится представление MMF.

Чтобы заставить работать MMF, объект должен быть скопирован из кучи GC в общую память. Это требует сериализации. Класс .NET 4.0 называется MemoryMappedViewStream. Вы, вероятно, можете видеть, куда это идет, это неотличимо от использования именованного канала или сокета. Получение данных в и из MMF требует одинакового усилия. MMF лишь немного более эффективен, поскольку базовый буфер не находится в пуле памяти ядра.

Ты можешь нарушить правила и сделать это сегодня. Вы можете P / Invoke CreateFileMapping, OpenFileMapping и MapViewOfFile вам нужно создать MMF. И используйте ключевое слово unsafe, чтобы вы могли создавать указатели. Вам нужно будет использовать типы значений (например, struct) для элементов общей памяти или класс Marshal.

4 голосов
/ 05 января 2010

IPC

Если вы говорите о межпроцессном взаимодействии. Существует несколько возможностей, таких как использование сокетов tcp / udp, почтовых ящиков, именованных каналов, файлов с отображенной памятью, сообщений Windows и т. Д.

.Net также предлагает IPC более высокого уровня, например .Net remoting и WCF , в которых используются упомянутые выше методы. Подробнее об этом можно прочитать здесь .

Файлы, отображенные в память

Если вы действительно хотите поделиться блоком памяти вместо связи, то, возможно, вам нужны файлы с отображением в памяти. .Net 4.0 имеет для этого MemoryMappedFile . Если вы не используете или не можете использовать .Net 4.0, вы можете реализовать его самостоятельно, как в этом примере win32 . Или вы можете попробовать этот код или посмотреть, можете ли вы использовать MemoryMappedFileStream, упомянутый здесь и здесь . Или используйте этот FileMap class.

1 голос
/ 05 января 2010

Используйте именованную трубу .

Это механизм, который позволяет одному процессу записывать последовательные данные в поток, из которого другой процесс может читать.

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

0 голосов
/ 12 февраля 2010
0 голосов
/ 05 января 2010

Как уже упоминалось, используйте Memory Mapped Files. Реализация для .NET <4 доступна по адресу: <a href="http://github.com/tomasr/filemap/" rel="nofollow noreferrer">http://github.com/tomasr/filemap/
Я использовал, и это работает безупречно. У вас могут возникнуть проблемы с безопасностью при совместном использовании процессов с повышенными / не повышенными правами - решение состоит в том, чтобы инициализировать отображенный в памяти файл в процессе с повышенными правами и соответственно установить его атрибуты безопасности.

...