Click here to Skip to main content
Click here to Skip to main content
Go to top

InterprocessSingleton - Convenient Template to Use Shared Memory Objects

, 2 Feb 2009
Rate this:
Please Sign up or sign in to vote.
This article describes basic concepts and code of C++ template which provides simple access to shared memory objects

Introduction

Interprocess communication is an important part of many distributed systems. Many libraries, such as Boost, give mechanisms for interprocess communication. Such a concept, as shared memory is one of the fastest mechanisms of data transmission between processes by one computer. This article represents a convenient template to work with objects in shared memory.

Required Technical Background

The basic concepts that were laid in the basis of the project are Boost.Interprocess and Boost.Serialization.
The library encapsulates interaction with Boost.Interprocess, thus the user does not need to know features of the library.

Boost.Serialization

Let's take a closer look at the Boost.Serialization library. The given generalized library provides convenient mechanisms for serialization/deserialization of objects, for example, their transfer on a network. In the given project, it is used for an object premise in a shared memory. To make object serializable, it is necessary to implement a method serialize or to steam methods load/save.

Example - method serialize is implemented, it both loads and stores data in archive:

#include <boost/serialization/string.hpp>
#include <boost/serialization/vector.hpp>

class SeriazableClass
{
    // That line is added because serialize is private in this class
    friend class boost::serialization::access;

    std::string m_strValue;
    std::vector< std::string > m_vData;

    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & m_strValue;
        ar & m_vData;
    }

public:
    SerializableClass()
    {
        m_strValue = "test";
        m_vData.push_back( "vector_test1" );
        m_vData.push_back( "vector_test2" );
    }
};

Basic Ideas

The idea of Singleton design pattern is put in a template basis:

  • Unique instance of class creation
  • Maintenance of a uniform point of access to an interprocess shared object
  • Simple use of global objects

InterprocessSingleton is used to store serializable objects in shared memory.

The basic methods of InterprocessSingleton template are:

  • T& Instance() - Returns the reference to the global object
  • void Commit() - Keeps the current object in shared memory
  • void Clear() - Completely clears an object in shared memory

Also, a revision of the last stored object remains in the shared memory. Thus, the object is loaded from shared memory only when revision of the kept object is greater than revision of the current object in process. Access on read/write in shared memory is synchronised by interprocess mutex.

Method Instance() does the job, described above.

Important note: In shared segment, that object remains for which Commit() has been called last. That is, if instances of one shared object are simultaneously edited in different processes, and then Commit is called, in memory will remain the object for which Commit() was called last.

The basic scheme of work is as follows:

  1. Retrieving of the reference to the global object by call to Instance()
  2. Work and change an object
  3. Save changes in the shared memory by call to Commit()

It is also recommended to call Clear() method at the start of the main process to clear the previous shared instance of the object.

Using the Code

The basic principle of the following examples is that when you start several copies of the application, the data will remain in the shared area.

Example 1 - Use with POD (Plain Old Data)

#include <interprocess.hpp>
#include <iostream>

int main()
{
    // Retrieve the reference to the global object
    int& nValue = InterprocessSingleton< int >::Instance();
    // Print a value of the object
    std::cout << "Value: " << nValue << std::endl;
    // Change the object
    nValue += 10;
    // Save changes
    InterprocessSingleton< int >::Commit();

    return 0;
}

Example 2 - Non-POD Data

#include <interprocess.hpp>
#include <vector>
#include <boost/serialization/vector.hpp>
#include <iostream>

int main()
{
    // Retrieve the reference to the global object
    std::vector< int >& vData = InterprocessSingleton< std::vector< int > >::Instance();
    std::cout << "Container size: " << vData.size() << std::endl;
    // Change the object
    vData.push_back( 10 );
    // Save changes
    InterprocessSingleton< std::vector< int > >::Commit();

    return 0;
}

Example 3 - Own Class

#include <interprocess.hpp>
#include <vector>
#include <iostream>

class MyClass
{
    friend class boost::serialization::access;

    std::string m_strValue1;
    int m_nValue2;

    // Implement that method to make object serializable
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & m_strValue1;
        ar & m_nValue2;
    }

    public:
        void PrintStatus()
        {
            std::cout << "String: " << m_strValue1 << std::endl;
            std::cout << "Integer: " << m_nValue2 << std::endl;
        }

        void ChangeClass()
        {
            m_strValue1 += "1";
            m_nValue2++;
        }
};

int main()
{
    MyClass& obj = InterprocessSingleton< MyClass >::Instance();
    obj.PrintStatus();
    obj.ChangeClass();
    InterprocessSingleton< MyClass >::Commit();

    return 0;
}

Points of Interest

I look forward to getting your comments and suggestions.

History

  • 1st February, 2009: First version

License

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

Share

About the Author

Eugene Bolotin
Software Developer
Russian Federation Russian Federation
No Biography provided

Comments and Discussions

 
QuestionHow to implement Singleton design pattern as a template? PinmemberAndreBroz10-Feb-09 20:30 
IMHO strictly speaking MyClass is not a singleton. There is nothing to prevent creation of another instance of the class. I've tried once to implement Singleton design pattern as a template but came up just with MFC style solution using macros
AnswerRe: How to implement Singleton design pattern as a template? PinmemberEugene Bolotin11-Feb-09 0:24 
GeneralRe: How to implement Singleton design pattern as a template? PinmemberAndreBroz11-Feb-09 23:44 

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

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

| Advertise | Privacy | Mobile
Web01 | 2.8.140921.1 | Last Updated 2 Feb 2009
Article Copyright 2009 by Eugene Bolotin
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid