Daniel Kamil Kozar
Daniel Kamil Kozar

Reputation: 19306

How to force the order of execution of two processes?

I have a parent process which spawns a certain number of child processes. Those child processes do some work and send the parent a message with the results via a interprocess message queue. However, I would also like the child processes to wait for the parent process to send them an acknowledgement that the message has been properly received and processed, and terminate only after receiving such a signal from the parent.

Right now, the code looks more or less like this :

parent                      child
spawn process
wait for message            do processing
                            send message
receive message             wait on condvar
save the message
notify the condvar          resume execution
wait for child termination  terminate

Which, of course, leads to a deadlock if the parent does the notify on the condvar before the child even begins to wait on it - if that happens, then the parent waits for the child to exit, and the child waits for a signal on the condition variable.

So, my question is : how to ensure that the child always executes wait in the first place, that is before the parent executes notify? Or am I going about the whole problem completely wrong?

Thank you in advance.

Upvotes: 1

Views: 544

Answers (2)

Martin James
Martin James

Reputation: 24887

Use an inter-process named semaphore or event - something that holds state, so that even if the parent signals before the child is waiting, the signal will still be received.

Upvotes: 1

Jan Hudec
Jan Hudec

Reputation: 76346

Yes, you are approaching the problem in wrong way. Or rather, using condvars the way they are not supposed to work. Condvar is a mean to notify the other thread that "something", a condition, has changed. It's that condition that allows the thread to terminate.

You need three elements to use condvar: condition, mutex and the condvar itself. Than the notifying thread will do:

{
    unique_lock(mutex);
    condition = true;
    condvar.notify();
}

and waiting thread will do:

{
    unique_lock(mutex);
    while(!condition)
        condvar.wait(mutex);
}

(using RAII for locking the mutex so I don't spread perception that calling .lock() and .unlock() methods directly is ever a good idea)

And note, that the while is important. wait may wake up spuriously even when not notified!

Upvotes: 2

Related Questions