Click here to Skip to main content
15,881,600 members
Articles / Desktop Programming / Win32

Ultimate Shared Memory: A Flexible Class for Interprocess Memory Sharing

Rate me:
Please Sign up or sign in to vote.
4.81/5 (22 votes)
13 Feb 2019CPOL3 min read 56.1K   49   26
A flexible memory sharing class across processes and threads with locking support

Introduction

This is a template class for sharing memory across threads or processes in Windows. It provides locking mechanisms, notifications and more!

Using the Code

Instantiation of the Class

C++
// usm(const wchar_t* string_id = 0,bool Init = false,size_t csz = 1048576,DWORD MaxTh = 100)
usm<char> sm(L"{4BF41A4E-ACF9-4E1D-A479-14DE9FF83BC2}",false,1000,100);
  • string_id is a string that uniquely identifies kernel objects for this shared memory. All instances of usm that use the same string_id are accessing the same memory. It's recommended to use a CLSID value to avoid possible collisions with other applications using usm.
    If you pass 0, then the object is left uninitialized. To initialize the object, you must call CreateInit which takes the same arguments as the constructor.
  • Init specifies whether initialization of the object must be included in the constructor. If this is true and an error occurs, the constructor throws an exception.
  • csz specifies the number of items to allocate. Total memory allocation is csz*sizeof(char) in the above example.
  • MaxTh is the maximum number of threads that will be accessing the shared memory. This must be the same number in any instances of the class that share the same string_id, or memory corruption will occur.

The library allocates memory to store events for each thread, so MaxTh must be the same in all instances of the class that use the same memory (i.e., same string_id).

Initialization of the Class

C++
//  int Initialize();

This function creates the kernel object handles required for synchronization. Calling End() destroys these handles. Initialize() returns 1 on success, and -1 on error. If Initialize() fails, End() cleans up all remaining handles. The destructor of the class also calls End().

If another thread is writing to the shared memory, this function waits until the writing is over.

Reading Shared Memory

C++
// unsigned long long ReadData(T* b,size_t sz,size_t offset = 0,bool FailIfNotReady = false);

This function (which internally calls BeginRead() and EndRead()) does the following:

  • If FailfNotReady is true and any writing thread has not finished writing, the function immediately returns -1. If FailIfNotReady is false, the function waits until any writing thread has finished writing.
  • Marks the current state of the calling thread as reading. This forces any writing thread to wait until reading is finished.
  • Reads the data.
  • Marks the state of the calling thread as not reading. This allows any writing thread to resume (as long as there are no more reading threads).
  • Returns the same value as sz.

Writing Shared Memory

C++
// unsigned long long WriteData(const T* b,size_t sz,size_t offset = 0,bool FailIfNotReady = false);

This function (which internally calls BeginWrite() and EndWrite()) does the following:

  • If FailfNotReady is true and any other thread is writing or reading, the function immediately returns -1. If FailIfNotReady is false, the function waits until any other writing or reading thread has finished.
  • Marks the current state of the calling thread as writing. This forces any other thread (reading or writing) to wait until writing is finished. This also forces any thread that is initializing the object with Initialize() to wait.
  • Writes the data.
  • Marks the state of the calling thread as not writing. This allows any other writing or reading thread to resume. The function also sets an event that the memory has been written.
  • Returns the same value as sz.

If you need the pointer to the data, you can call BeginRead() (which must be followed by a call to EndRead()) and BeginWrite() (which must be followed by a call to EndWrite()).

C++
const T* BeginRead(bool FailOnNotReady = false);
void EndRead();
T* BeginWrite(bool FailOnNotReady = false);
void EndWrite();

Notifications

C++
// DWORD NotifyOnRead(bool Wait);
// DWORD NotifyWrite(bool Wait);
  • If you call NotifyOnRead, this function with Wait == false, then the function returns:
    • -1 if the function fails
    • -2 if there are no other registered threads
    • WAIT_TIMEOUT if any thread is still reading
    • WAIT_OBJECT_0 or a greater value if any of the reading threads has finished
  • If you call NotifyOnRead with Wait == true, the return values are the same, except that the function does not return if all threads are still reading.

NotifyOnWrite returns WAIT_OBJECT_0 if a thread has just finished writing (note that this event is auto-reset). If a thread is not writing or still writing, NotifyOnWrite either returns WAIT_TIMEOUT (if you call it with Wait == false) or it waits until a thread has completed writing.

Hopefully, this class will be helpful for you. It's already very helpful for me.
Good luck!

History

  • 2/11/2014 - Added the ability to initialize later, and added copy constructor and operator =, and added offset to read/write functions
  • 1/11/2014 - First release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Greece Greece
I'm working in C++, PHP , Java, Windows, iOS, Android and Web (HTML/Javascript/CSS).

I 've a PhD in Digital Signal Processing and Artificial Intelligence and I specialize in Pro Audio and AI applications.

My home page: https://www.turbo-play.com

Comments and Discussions

 
Questionfloat type error Pin
smart_dummies30-May-16 22:58
smart_dummies30-May-16 22:58 
AnswerRe: float type error Pin
Michael Chourdakis13-Jun-16 13:03
mvaMichael Chourdakis13-Jun-16 13:03 
QuestionSample working code? Pin
iammaz2-Dec-15 17:02
iammaz2-Dec-15 17:02 
AnswerRe: Sample working code? Pin
Michael Chourdakis2-Dec-15 18:19
mvaMichael Chourdakis2-Dec-15 18:19 
GeneralRe: Sample working code? Pin
iammaz2-Dec-15 19:11
iammaz2-Dec-15 19:11 
AnswerRe: Sample working code? Pin
iammaz2-Dec-15 19:10
iammaz2-Dec-15 19:10 
GeneralRe: Sample working code? Pin
Michael Chourdakis2-Dec-15 23:25
mvaMichael Chourdakis2-Dec-15 23:25 
GeneralRe: Sample working code? Pin
iammaz6-Dec-15 21:29
iammaz6-Dec-15 21:29 
GeneralRe: Sample working code? Pin
iammaz6-Dec-15 23:02
iammaz6-Dec-15 23:02 
GeneralRe: Sample working code? Pin
iammaz7-Dec-15 15:15
iammaz7-Dec-15 15:15 
GeneralTo make it work between a windows service and client app read this thread Pin
iammaz8-Dec-15 12:38
iammaz8-Dec-15 12:38 
Questiongreate work!! too. Pin
yyusea12-Aug-15 20:26
yyusea12-Aug-15 20:26 
GeneralSame here: Great Work!! Pin
Member 118823894-Aug-15 11:29
Member 118823894-Aug-15 11:29 
QuestionWM_COPYDATA Pin
zapsolution10-Nov-14 3:47
zapsolution10-Nov-14 3:47 
AnswerRe: WM_COPYDATA Pin
Michael Chourdakis10-Nov-14 4:15
mvaMichael Chourdakis10-Nov-14 4:15 
GeneralRe: WM_COPYDATA Pin
zapsolution10-Nov-14 4:32
zapsolution10-Nov-14 4:32 
WM_COPYDATA has always served me well.

I am using it to perform real time animation with OpenGL visual plugins, altogether with synchronization using a private message based on the use of RegisterWindowMessage.
gP.ZWPNOTIFICATION = RegisterWindowMessageA("ZWPnotification");

I am also using memory mapped file, and couldn't see any speed difference in my own testing.

...
GeneralRe: WM_COPYDATA Pin
Michael Chourdakis10-Nov-14 4:35
mvaMichael Chourdakis10-Nov-14 4:35 
GeneralRe: WM_COPYDATA Pin
zapsolution10-Nov-14 4:51
zapsolution10-Nov-14 4:51 
GeneralRe: WM_COPYDATA Pin
Michael Chourdakis10-Nov-14 4:53
mvaMichael Chourdakis10-Nov-14 4:53 
GeneralRe: WM_COPYDATA Pin
zapsolution10-Nov-14 5:06
zapsolution10-Nov-14 5:06 
Questionin .net you can use memory mapped file Pin
Sacha Barber3-Nov-14 19:25
Sacha Barber3-Nov-14 19:25 
AnswerRe: in .net you can use memory mapped file Pin
BManfred3-Nov-14 21:43
BManfred3-Nov-14 21:43 
GeneralRe: in .net you can use memory mapped file Pin
Sacha Barber4-Nov-14 2:46
Sacha Barber4-Nov-14 2:46 
QuestionAny advantage over boost interprocess memory sharing? Pin
Shao Voon Wong3-Nov-14 16:50
mvaShao Voon Wong3-Nov-14 16:50 
AnswerRe: Any advantage over boost interprocess memory sharing? Pin
Michael Chourdakis3-Nov-14 19:07
mvaMichael Chourdakis3-Nov-14 19:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.