Shared Memory Mapped File

  
  1. Shared Memory Mapped File Linux
  2. Shared Memory Mapped File C#
  3. Java Shared Memory Mapped File
  4. Shared Memory Mapped File In Windows
  5. Difference Between Shared Memory And Memory Mapped File
4 Jan 2011CPOL

To share data, multiple processes can use memory-mapped files that the system paging file stores. Creating Named Shared Memory To share data, multiple processes can use memory-mapped files that the system paging file stores. Mar 30, 2017  Memory-mapped files can be shared across multiple processes. Processes can map to the same memory-mapped file by using a common name that is assigned by the process that created the file. To work with a memory-mapped file, you must create a view of the entire memory-mapped file.

An introduction to MMF and shared memory in .NET applications.

Introduction

First of all, what is a memory-mapped file or MMF? MMF is a kernel object that maps a disk file to a region of memory address space as the committed physical storage. In plain English, MMF allows you to reserve a range of addresses and use a disk file as the physical storage for the reserved addresses. When a MMF is created, you access the mapped disk file as if you were accessing memory. MMF makes accessing files easy. For example, Windows loads EXEs or DLLs using MMF. MMF is a corner stone for almost all modern forms of inter-process communication (or IPC). I felt inconvenient when early .NET Framework releases did not support MMF. The good news is that starting version 4, .NET Framework has built-in support for MMF!

This article has two objectives:

  • The tutorial will focus on sample MMF applications. For theoretical discussions, refer to Jeffery Richter's classic text 'Programming Applications for Microsoft Windows - 4th Ed.', Chapter 17. For .NET Framework 4 MMF specifications, check out this MSDN page.
  • The tutorial is written for programmers who are familiar with the C# language. General knowledge of C++ shall help you to understand the discussion of shared memory transparency. In order to build and run these samples, you should have Visual Studio 2010 installed on your machine.

Imagine you have got some modules or applications written in native C/C++ and you want to use them. The old modules use MMF to exchange data. Without MMF support in earlier .NET, you can do two things among others:

  • Platform Invoke Win32 MMF support. You need to handle lots of marshalling between managed and unmanaged worlds.
  • You can always use Windows debug symbol support, which allows to access variables as symbols. However, this mechanism is rather involving and beyond beginners' comfort level. You have to fiddle with marshalling as well.

With .NET Framework 4, you just write an MMF-enabled application to exchange data with old C/C++ applications directly. This article will demonstrate how to write MMF-enabled .NET applications. We start from basic examples. Then we'll move on to more advanced use of MMF in the shared memory design.

Simple MMF Applications

We demonstrate three sample MMF applications:

  • File Copy
  • Simple IPC
  • Single Instance

File Copy

The first sample program copies contents from an existing file to a new file. The source code is self-explaining, and listed as follows:

A number of things are noticeable. We first call the static method CreateFromFile() to create an MMF object. The MemoryMappedFile class provides several overloaded static methods:

Her death unleashes the Sands of Time, which strike the Prince and threaten to destroy everything he holds dear. Download prince of persia t2t. Cast to the streets, hunted as a fugitive, the Prince soon discovers that the Sands have tainted him, too.

  • CreateFromFile() creates an MMF from the existing disk file.
  • CreateNew() creates an MMF based on the system page file.
  • CreateOrOpen() creates a new MMF or opens an existing MMF.
  • OpenExisting() opens an existing MMF.

The second and third methods create non-persisted MMF. In Windows implementation, non-persisted MMF is backed by the system page file. Three trapped tigers silent earthling bandcamp. It only exists during the scope of the MMF.

We called CreatedViewAccessor() to create a view to the MMF we created. The MMF view can be read-only, or read-and-write, depending on the accessibility parameter we passed to the call. The view can map all or portions of the MMF. As you access the data through a view, you can only access the data that is mapped in the view. There are also two overloaded methods to create a view for the MMF:

  • CreateViewAccessor() creates an access object from the MMF.
  • CreateViewStream() creates a stream from the MMF.

Obviously, you can use CreateViewStream() to modify the above sample application, which I leave to you as an exercise. The checks for the existence of copy-to file are omitted for brevity. You should add logic to handle such cases as that the copy-to file already exists.

Simple IPC

In the second example, we'll discuss how two applications exchange data via MMF. Obviously, we could extend the copy file example in such a way that two applications can exchange data through the disk file. Basically, one application writes data to the file and the other reads data from the same file.

A better mechanism is to exchange data without depending on the presence of disk files. MMF can support exactly that. Here is the complete code to create an MMF and write some bytes to it:

Apparently, we created an MMF differently this time. Firstly, we called CreateNew() which has been discussed earlier. Secondly, the first parameter of CreateNew() is the name of the MMF we create. We call this MMF a named MMF. The purpose of naming is to identify the MMF among foreign processes.

Here is the code segment for accessing the MMF and reading data from it:

In the reader code, we call the CreateOrOpen() method because the MMF may have already been created. Basically, if it was created, we open it. If not, we create it. It is critical that you pass the correct name to the call. Otherwise, you're creating a new MMF, instead of sharing the existing one as you thought.

Shared Memory Mapped File Linux

You may be wondering why we create a mutex in both the writer and reader code. It is for synchronizing data access between the two processes. The writer locks the mutex, writes to the MMF, and then releases the lock. The reader waits on the lock until the writer finishes writing and releases it. Then the reader reads the data from the MMF. That is how we ensure data integrity, which is no different from other forms of IPC.

Single Instance

The so called 'Single Instance' means that you only want one instance of your program running at a given time. Since MMF can be uniquely named, you can use MMF as a token to indicate whether your application is already running. The idea is simple: one cannot create the same named MMF twice. Here is the code segment:

Hope you have found MMF useful. We are ready to explore more of its power.

Shared Memory Mapped File C#

Shared Memory

You have probably heard of 'Shared Memory' now and then. This terminology usually refers to a data block that is shared by more than one application that is running on one or more computer stations. There are several different implementations of shared memory solutions, hardware, software, or combined. This article is focused on MMF based shared memory design, which is an extension of what you've seen in the Simple IPC sample.

When you design a shared memory solution, some basic features are commonly required:

  • Shared memory shall be data oriented, i.e., all the data to be exchanged should be wrapped in a structure for easy access.
  • Access to the shared memory is transparent, i.e., using the shared memory as if you were using the data structure directly.
  • Access to the shared memory shall be protected to ensure data integrity.

The following code represents a limited implementation of a shared memory class in .NET 4:

Now we write a sample application to use this SharedMemory class. First we create some data.

To keep the code simple, I declared all attributes in the structures public. In the real world, you should protect the data and expose them through properties. Anyway, now we write a class to use SharedMemory. The class shall read the data from the shared memory block, modify the data, and finally write the changes back to the shared memory.

The code is by all means very simple. Build the project 'SharedMemoryClient'. Run two instances of it. You will notice that the data the second instance reads contains some changes made by the first instance.

Java Shared Memory Mapped File

There are a number of places you should pay attention to:

Shared Memory Mapped File In Windows

  • ShareMemory is a generic (parameterized) class that takes a structure as the parameter to the class. That structure parameter is a place holder for the data to be shared.
  • When protecting the shared memory, we only lock writing to, not reading from, the data block. This is purely a practical consideration for the sake of performance. You may protect both reading and writing depending on applications.
  • The structure copy we performed is a shallow, not deep one. In other worlds, the data we exchange should not contain reference types. This makes sense as we have no knowledge of what the data block actually contains. Shallow copy is usually enough as shared memory is a data oriented, not object oriented design.

Difference Between Shared Memory And Memory Mapped File

Points of Interest

The implementation of Shared Memory presented above does not fully meet the requirements of transparency, mainly due to the lack of support for pointer operations in C#. In native C++, overloading the operator '->' would provide a better solution. Unfortunately, we couldn't overload the C# operator '.' as we do with the C++ operator '->'. As such, the combined use of property and structure copy is a somehow compromised solution.

As we've seen, there could be different implementations of MMF. C++ and C# implement MMF differently. Managed and unmanaged platforms also implement MMF differently. One question we haven't addressed is: can .NET 4 applications exchange data with applications that were written and built in VC++ 6.0? The answer is yes. In Windows internals, MMF is a named kernel object, like a mutex. What really matters with MMF is its name, size of the memory it reserves, and offset of the memory address. Note that the size and offset are important because you want to ensure the data you are accessing is not truncated or otherwise corrupted!

History

This is the first revision of the article and the source code.