Reputation: 433
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
Reputation: 1917
See "shared memory" in Boost Interprocess: http://www.boost.org/doc/libs/1_63_0/doc/html/interprocess/sharedmemorybetweenprocesses.html
Upvotes: 1
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
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
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.
Upvotes: 1
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