MemoryMappedFile не работает с 2 процессами? - PullRequest
2 голосов
/ 18 марта 2012

Я сделал простой тест с MemoryMappedFile, когда msdn говорит:

2 процесса, 1 файл отображения памяти:

  • первый процесс добавляет строку "1"
  • первый процесс ждет
  • второй процесс добавляет строку «2» и завершается
  • первый процесс теперь читает весь отображенный файл памяти

процесс A:

using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("testmap", 10000))
            {
                bool mutexCreated;
                Mutex mutex = new Mutex(true, "testmapmutex", out mutexCreated);
                using (MemoryMappedViewStream stream = mmf.CreateViewStream())
                {
                    BinaryWriter writer = new BinaryWriter(stream, Encoding.UTF8);
                    writer.Write("1");
                }
                mutex.ReleaseMutex();
                Console.WriteLine("Start Process B and press ENTER to continue.");
                Console.ReadLine();
                mutex.WaitOne();
                using (MemoryMappedViewStream stream = mmf.CreateViewStream())
                {
                    BinaryReader reader = new BinaryReader(stream, Encoding.UTF8);
                    Console.WriteLine("Process A says: {0}", reader.ReadString());
                    Console.WriteLine("Process B says: {0}", reader.ReadString());
                }
                mutex.ReleaseMutex();
            }

процесс B:

 using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("testmap"))
                {
                    Mutex mutex = Mutex.OpenExisting("testmapmutex");
                    mutex.WaitOne();
                    using (MemoryMappedViewStream stream = mmf.CreateViewStream(1, 0))
                    {
                        BinaryWriter writer = new BinaryWriter(stream, Encoding.UTF8);
                        writer.Write("2");
                    }
                    mutex.ReleaseMutex();
                }

Результат:

enter image description here

Ху?

Где "1", "2"?

Однако, если я запускаю ТОЛЬКО первый процесс (без активации процесса B), я получаю:

enter image description here

Чего мне не хватает?

Я ожидаю увидеть:

Process A says: 1
Process B says: 2

Ответы [ 2 ]

7 голосов
/ 18 марта 2012

Вы боретесь с деталями реализации BinaryWriter.Write (строка).Сначала записывается длина строки, необходимая для того, чтобы BinaryReader знал, сколько символов ему нужно прочитать при обратном чтении строки.Для коротких строк, таких как «1», он записывает один байт для хранения длины.

Так что смещение, которое вы передаете CreateViewStream (), является неправильным, пропуск 1 сделает его перезаписать частьстроки, написанной процессом A. Символ смайлика, который вы видите, является глифом для (char) 1.Байт длины, записанный процессом B.

Файлы, отображаемые в память, вызывают проблемы в управляемом коде.Обычно вы читаете и пишете им, объявляя структуру для установки макета и используя указатели для доступа к представлению, но это требует небезопасного кода.Потоки - довольно плохая абстракция для куска памяти, но необходимое зло.Кроме того, причина, по которой MMF стали доступны в .NET, заняла так много времени.

0 голосов
/ 18 марта 2012

РЕДАКТИРОВАТЬ

Я заметил одну явно странную вещь в коде ProcessB. Этот код

using (MemoryMappedViewStream stream = mmf.CreateViewStream(1, 0))

создает представление из первого байта, но строки в .NET составляют 2 байта. Я думаю, вам должно быть достаточно, чтобы 1->2 стал 2. Таким образом, смещение представления ProcessB от начала отображенного файла будет после того, как уже вставит строку "1" из ProcessA.

В вашем случае кажется , что вы перекрываете их.

Надеюсь, это поможет.

...