user1971455
user1971455

Reputation: 433

c++ sharing single class object between multiple processes

I have a relatively complex class in c++. It works perfectly when used within one process. However, now I want multiple processes to be able to share one object instance of this class. One process (Master) will access read and write functions of the object, while the other 2 processes (Slave) will only use the read functions. I want to modify the class as little as possible. So far I have considered singletons and shared memory, but neither seems ideal or straightforward. This is a research application that will only ever be used by me on Linux. What is the simplest possible solution?

Thanks so much!

Edit: To be absolutely clear, the asker is interested in sharing an object across multiple processes, not threads.

Upvotes: 12

Views: 11803

Answers (5)

alex
alex

Reputation: 1917

See "shared memory" in Boost Interprocess: http://www.boost.org/doc/libs/1_63_0/doc/html/interprocess/sharedmemorybetweenprocesses.html

Upvotes: 1

ryanbwork
ryanbwork

Reputation: 2153

One option is to have both the master and slave processes create instances of the same object. Because the master process will be the only one to modify this 'shared' object, it must only alert the slaves processes to any changes it makes to the 'shared' object. To do this, you could setup a messaging system which the master process will use to communicate changes to the shared object with the slave processes. The drawback here is that the slave processes may reference the shared object when it is out of sync with the master, but this is a common problem in replication. Also, you could use an RPC overlay to further make the master/slave applications easier to develop/maintain.

I'll try and provide a very high level example of this design below. Forgive me for utilizing real code and psuedo code side-by-side; I didn't want to fully code this, but also didn't want it to just be made up of comments :)

Here's our shared object that gets defined in both master/slave code

struct sharedobj {
  int var1;
};

Here's an example of the master process updating the shared object and propagating changes

int counter = 0;
sharedobj mysharedobj;
while(true){
  //update the local version first
  mysharedobj.var1 = counter++;

  //then call some function to push these changes to the slaves
  updateSharedObj(mysharedobj);
}

Here's the function that propagates the master's changes to the slaves;

updatedSharedObj(sharedobj obj){

  //set up some sort of message that encompasses these changes
  string msg = "var1:" + the string value of obj.var1;

  //go through the set of slave processes
  //if we've just done basic messaging, maybe we have a socket open for each process
  while(socketit != socketlist.end()){

    //send message to slave
    send(*socketit, msg.c_str(),msg.length(),0);

  }

}

And here's the slave code that receives these changes and updates its 'shared' object; most likely running in another thread so slave can run without having to stop and check for object updates.

while(true){

  //wait on the socket for updates
  read(mysock,msgbuf,msgbufsize,0);

  //parse the msgbuf
  int newv1 = the int value of var1 from the msg;

  //if we're in another thread we need to synchronize access to the object between
  //update thread and slave
  pthread_mutex_lock(&objlock);

  //update the value of var1
  sharedobj.var1 = newv1;

  //and release the lock
  pthread_mutex_unlock(&objlock);

}

Upvotes: 1

mistapink
mistapink

Reputation: 1956

One idea might be to use socket or a socket library to share the data amongst the processes. A library which seems to be very handy for that might be ØMQ. You can also try to use Boost::Asio which is a bit more complex.

You can find a small example for ØMQ here.

Upvotes: 1

MobA11y
MobA11y

Reputation: 18860

I think the simplest coding solution would be a singleton with a global(or class instance) mutex, though the singleton part of that is optional. I personally think singletons to be an overused idiom. Up to you whether you think that is good design in this case or not. Really, adding the global mutex is all you need.

For the interprocess portion, I recommend boost.

http://www.boost.org/doc/libs/1_36_0/doc/html/interprocess/synchronization_mechanisms.html#interprocess.synchronization_mechanisms.semaphores.semaphores_interprocess_semaphores

Upvotes: 1

Minthos
Minthos

Reputation: 900

Inter-process communication is never simple. You may want to use a library for IPC/RPC and expose only the function the slaves use to read data, not the entire class.

I can't give you any good recommendations because I have never found a library that made it simple and I don't have much experience with it.

Upvotes: 4

Related Questions