views:

186

answers:

6

Hi,

I use SysV shared memory to let two processes communicate with each other. I do not want the code to become to complex so I wondered if I really had to use semaphores to synchronize the access to the shared memory. In my C/C++ program the parent process reads from the shared memory and the child process writes to the shared memory. I wrote two test applications to see if I could produce some kind of error like a segmentation fault, but I couldn't (Ubuntu 10.04 64bit). Even two processes writing non stop in a while loop to the same shared memory did not produce any error.

I hope someone has experience concerning this matter and can tell me if I really must use semaphores to synchronize the access or if I am OK without synchronization.

Thanks

+4  A: 

If you don't use some sort of mutex, you're exposing yourself to weird and wonderful timing bugs related to interruption more than anything else.

Suppose your child is partway through a write to the shared memory when it's preempted. The shared memory is now in a 'bad' state - part of it relates to one state of the child process, the rest to the one before that - and it's possible your parent could get reactivated before the child does. Then, you have corrupted state.

You might be able to get away with this in the short term, but you will find weird bugs later.

DDaviesBrackett
Thanks, I appreciate your answer.
walki
+1  A: 

As mentioned it is a matter of data integrity, not segfaults.

If this is a problem use: pipes - which is simple IPC system to implement, maybe 6 lines of code in parent, the same in child

http://tldp.org/LDP/lpg/node11.html

jim mcnamara
+1  A: 

You will not produce a segmentation fault by writing to a properly mapped memory address, no matter how many processes attempt to do it 'concurrently'. The purpose of synchronization is rather to maintain data consistency.

You can avoid semaphores and mutex locks if the following conditions are all true:

  1. You have only one thread write to a given address.

  2. The data written is atomic -- meaning it can be transferred in one I/O operation. Simple things like chars and ints are typically atomic when transferred. Many structs, strings, and arrays are NOT atomic operations when copied since they are often composed of multiple I/O-size elements.

  3. The validity of the data item doesn't rely on any other piece of data.

  4. You use the keyword 'volatile' when accessing the data to avoid a stale dereference.

If any of the above are not met then you must use synchronization of some sort if you want to guarantee the data is consistent and valid.

Amardeep
Thanks, your answer is very detailed and helpful.
walki
You can skip using 'volatile' if you use proper compiler and hardware memory barrier operations.
Zan Lynx
+1  A: 

In addition to all the fine responses - take a look at boost::interprocess library - very handy for keeping C++ STL-like containers in shared memory. It's implemented with POSIX shared memory on Unixen, not SysV, shmem_open(3) et al., which you might also be interested in.

Nikolai N Fetissov
Tkanks, Boost is very interesting. It reminds me the STL and it is more C++ than SysV.
walki
A: 

Here's a slightly different approach: if your can guarantee that your readers/writers would not preempt each other unexpectedly, you don't need to synchronize between them.

For example, you can guarantee that, on your Linux, if you use the scheduler policy SCHED_FIFO (see sched_setscheduler(2)) for all processes that access your shared memory AND if they are running at the same realtime priority AND they are all locked to the same CPU core (on multicore systems). Then if the reader is executing, it will be the only process executing until it chooses to wait on a condition or sleep on a timer. Even if the writer wakes up from some condition it was waiting on, during the read, the scheduler will not let the writer run until the reader is done.

Cubbi
A: 

Hi ,I would suggest to use one flag to indicate access permissions,Like the writter thread will make the flag-- and once writting is done writter thread can make it flag++,Reader thread also does the same. This way avoid using Mutex and locking overhead. I have used this and trust me flag-- and flag++ are atomic mostly :-)

Yusuf