Majenko
Majenko

Reputation: 1840

Synchronize two processes using two different states

I am trying to work out a way to synchronize two processes which share data.

Basically I have two processes linked using shared memory. I need process A to set some data in the shared memory area, then process B to read that data and act on it.

The sequence of events I am looking to have is:

  1. B blocks waiting for data available signal
  2. A writes data
  3. A signals data available
  4. B reads data
  5. B blocks waiting for data not available signal
  6. A signals data not available
  7. All goes back to the beginning.

In other terms, B would block until it got a "1" signal, get the data, then block again until that signal went to "0".

I have managed to emulate it OK using purely shared memory, but either I block using a while loop which consumes 100% of CPU time, or I use a while loop with a nanosleep in it which sometimes misses some of the signals.

I have tried using semaphores, but I can only find a way to wait for a zero, not for a one, and trying to use two semaphores just didn't work. I don't think semaphores are the way to go.

There will be numerous processes all accessing the same shared memory area, and all processes need to be notified when that shared memory has been modified.

It's basically trying to emulate a hardware data and control bus, where events are edge rather than level triggered. It's the transitions between states I am interested in, rather than the states themselves.

So, any ideas or thoughts?

Upvotes: 5

Views: 2169

Answers (4)

Rohit J
Rohit J

Reputation: 82

1 Single Reader & Single Writer
1 Single Reader & Single Writer This can be implemented using semaphores. In posix semaphore api, you have sem_wait() which will wait until value of the semaphore count is zero once it is incremented using sem_post from other process the wait will finish.

In this case you have to use 2 semaphores for synchronization.

process 1 (reader)
sem_wait(sem1);
.......
sem_post(sem2);

process 2(writer)
sem_wait(sem2);
.......
sem_post(sem1);

In this way you can achieve synchronization in shared memory.

Upvotes: 0

Jens Gustedt
Jens Gustedt

Reputation: 78903

In linux, all POSIX control structures (mutex, conditions, read-write-locks, semaphores) have an option such that they also can be used between processes if they reside in shared memory. For the process that you describe a classic mutex/condition pair seem to fit the job well. Look into the man pages of the ..._init functions for these structures.

Linux has other proper utilities such as "futex" to handle this even more efficiently. But these are probably not the right tools to start with.

Upvotes: 0

Nikolai Fetissov
Nikolai Fetissov

Reputation: 84169

Linux has its own eventfd(2) facility that you can incorporate into your normal poll/select loop. You can pass eventfd file descriptor from process to process through a UNIX socket the usual way, or just inherit it with fork(2).

Edit 0:

After re-reading the question I think one of your options is signals and process groups: start your "listening" processes under the same process group (setpgid(2)), then signal them all with negative pid argument to kill(2) or sigqueue(2). Again, Linux provides signalfd(2) for polling and avoiding slow signal trampolines.

Upvotes: 2

Kamran Amini
Kamran Amini

Reputation: 1062

If 2 processes are involved you can use a file , shared memory or even networking to pass the flag or signal. But if the processes are more, there may be some suitable solutions in modifying the kernel. There is one shared memory in your question, right ?! How the signals are passed now ?!

Upvotes: 0

Related Questions