in reply to Synchronising threads with signals (or not)
I am trying to synchronise two processes
I guess you mean threads not processes...
But in any case, synchronising two threads isn't really possible. At least not with any great accuracy.
A few scenarios:
- Let's say you are running on a single core system.
When your main thread 'signals' go -- in this case by incrementing your cond_var to 3 -- neither of the other two threads will be running, because your main thread has the cpu.
And when your main threads timeslice ends, only one of the other two threads can take over.
Which, you can never know, because the scheduler chooses.
And when, you can never know, because there may be a couple of dozen threads from other processes that are either a higher priority; or have simply been waiting longer, that get a timeslice between your main thread giving up its timeslice, and one of your other two threads getting one.
But, in any case, one of your other threads will see the signal before the other does.
It could not be different no matter what mechanism you use.
- You are running on a 2 core system.
If you are lucky, one of your other two threads might be running on the other core when your main thread signals. But more likely not.
And even if it was; it might be many timeslices before your other thread gets a timeslice and receives the signal.
- You are running on a 3 or more core system.
There is still no guarantee that all 3 of your threads will have timeslices at the moment your main thread signals.
Indeed, unless you are running on a system that has no system processes or threads at all -- no device drivers; no other applications; no clock; no interrupt handler etc. etc. -- the odds are very much stacked against it happening.
The problem here is designing software that requires synchronisation.
The best you can do -- assuming I've understood your application -- is first signal the recorder to start recording; then have it signal the player to start playing; and accept that there will be some small portion of dead space at the lead in of the recording.
You can minimise the dead space by setting the priority of your threads to real time -- assuming your OS supports that possibility -- but that still doesn't guarantee that they will see and react to signals immediately.
Also, the way you are using cond_wait() is wrong. As you are locking the wait variable, before you wait on it -- a requirement of the (crappy*) cond_var mechanism) -- and lock()s are mutually exclusive, only one of your threads will be able to enter the wait-state at a time.
And, unless you cond_signal(), which ever thread gets in first will never wake up, so the second thread will never get a look in (to achieve a lock). I'm not sure how you think what you have should work?
I'm loathed to offer any solution at this point as it is not clear to me that what you are trying to do -- synchronously release two threads from wait states -- is either possible or desirable.
If you are absolutely adamant that is is a requirement, then you'll need to look into using the two var version of the cond_wait() and cond_broadcast(). And you'll need to use separate lock_vars for each thread, but a common sig_var.
Read the docs carefully and expect it to be hard to wrap your brain around. And even when you've got it working, understand that the release of the two signaled threads will not happen either instantaneously or exactly synchronously.
(*Not really Perl/iThreads designer's fault; they simply chose to reflect the underlying pthreads mechanisms. It is they that are crap.)
|
---|