3
votes

I am currently developing a modular framework using shared memory in C & C++. The goal is to have independent programs in both C and C++, talk to each other through shared memory.

E.g. one program is responsible for reading a GPS and another responsible for processing the data from several sensors.

A master program will start all the slave programs (currently i am using fp = popen(./slave1/slave1,"r"); to do this) and then make shared memory segments that each slave can connect to. The thought behind this is that if a slave dies, it can be revived by the master and reconnect to the same shared memory segment.
Slaves can also be exchanged during runtime (e.g. switch one GPS with another).

The problem is that I spawn the slave via popen, and pass the shared memory ID to the slave. Via the pipe the slave transmits back the size needed. After this is done i want to reroute the slave's pipe to terminal to display debug messages and not pass through the master.

Suggestions are greatly appreciated, as well as other solutions to the issue. The key is to have some form of communication prior to setting up the shared memory.

4
It should be mentioned that this is a Linux system. - K_scheduler

4 Answers

1
votes

I suggest to use another mean to communicate. Named pipe are the way I think. Rerouting standard out/err will be tricky at best.

I suggest to use boost.interprocess to handle IPC. And be attentive to synchronization :)

my2c

1
votes

You may want to look into the SCM_RIGHTS transfer mode of unix domain sockets - this lets you pass a file descriptor across a local socket. This can be used to pass stderr and the like to your slave processes.

You can also pass shared memory segments as a file descriptor as well (at least on Linux). Create a file with a random name in /dev/shm and unlink it immediately. Now ftruncate to the desired size and mmap with MAP_SHARED. Now you have a shared memory segment tied to a file descriptor. One of the nice things about this approach is the shared memory segment is automatically destroyed if all processes holding it terminate.

Putting this together, you can pass your slaves one end of a unix domain socketpair(). Just leave the fd open over exec, and pass the fd number on the command line. Pass whatever configuration information you want as normal data over the socket pair, then hand over a file descriptor pointing to your shared memory segment.

0
votes

Pipes are not reroutable -- they go where they go when they were created. What you need to do is have the slave close the pipe when its done with it, and then reopen its stdout elsewhere. If you always want output to the terminal, you can use freopen("/dev/tty", "w", stdout), but then it will always go to the terminal -- you can't redirect it anywhere else.

0
votes

To address the specific issue, send debug messages to stderr, rather than stdout.