Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
463 views
in Technique[技术] by (71.8m points)

c# - MemoryMappedFile doesn't work with 2 processes?

I've made a simple test with a MemoryMappedFile as msdn says :

2 processes, 1 memory mapped file :

  • the first process adds the string "1"
  • the first process waits
  • the second process adds the string "2" and terminates
  • the first process now reads the whole memory mapped file

process 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();
            }

process 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();
                }

The result is :

enter image description here

Hu ?

Where is "1", "2" ?

However, if I run ONLY the first process ( without activating process B) I get :

enter image description here

What am I missing ?

I expect to see :

Process A says: 1
Process B says: 2
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You are battling an implementation detail of BinaryWriter.Write(string). It writes the length of the string first, required so that BinaryReader knows how many characters it needs to read when reading the string back. For short strings, like "1", it writes a single byte to store the length.

So the offset you pass to CreateViewStream() is wrong, passing 1 will make it overwrite part of the string written by process A. The smiley character you see is the glyph for (char)1. The length byte of the string written by process B.

Memory mapped files are troublesome in managed code. You normally read and write to them by declaring a struct to set the layout and using pointers to access the view but that requires unsafe code. Streams are a pretty poor abstraction for a chunk of memory but a necessary evil. Also the reason it took so long for MMFs to become available in .NET.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...