Situation
I've got a worker thread that's being triggered by a condition_variable to do some work. Basically it is working very good and as supposed.
Problem
However there's one problem: The thread launching the worker thread may get a long enough time slice to feed the data queue and notify the condition_variable when the worker thread is not ready yet, i.e. when it didn't reach the condition_variable.wait() line yet.
Is there any way I can wait for a worker thread until the first call to wait() is made so it's guaranteed that work will be processed when I notify the worker?
There's no reason to do that. When the worker thread is ready, it will do the work. It won't need to be triggered by a condition variable because it won't ever wait.
Waiting for something that has already happened is a coding error. If you might ever even think of doing that, you fundamentally don't understand condition variables.
Before a thread waits on a condition variable, it must make sure that there is something it needs to wait for. That thing must be protected by the mutex associated with the condition variable. And when the thread returns from the condition variable wait, it usually must re-test to see if it needs to wait again.
Related
I have a main program that needs to launch a number of threads that immediately wait on a condition_variable. The main program then enters a loop. Each iteration of the loop by the main program does a notify_all to awaken all the threads. The main program then waits for all the threads to complete their processing before beginning the next iteration of the main loop.
I know how to do this for one thread. I think I know how to do this with multiple threads, but I have a question with how the main program should go about waiting on all the threads. The main program cannot do it with join because the threads are going to wait for the next iteration of the main loop rather than terminate. So the main program has to do it with wait.
Each thread will of course notify the main program that it is complete for this iteration immediately before it goes back into wait. I know how to do notify and wait back and forth between the main program and one thread, and I know generally how to use condition_variables. I know how to avoid lost wakeups and spurious wakeup events, etc. But I'm a little fuzzy on how the main program is supposed to wait to be notified by all the threads before proceeding with the next iteration of the loop. Conceptually, the main program needs to wait on multiple condition_variables, one for each thread. But that's not how condition_variables work. You can only wait on one condition_variable at a time.
I can think of two ways to handle the main program waiting on all the threads. The two ways I can think of to do it is that the main program would be waiting on a single condition variable that all the threads would notify when they were done or that there would be multiple condition variables that the main program would be waiting on, one per thread, and the main program would wait for them one at a time. I'm sure I know how to make the latter case work. The question is whether it's possible to make the former case work. If it could work, I would picture a different Boolean variable that would be set by each thread when it finished an iteration. The main program's wait would have a predicate that tested each Boolean variable in turn. The wait processing would loop until it had found all the boolean variables turned on. So that's the question. Can I get by with one condition_variable that each thread notifies? Or do I need a separate condition_variable for each thread to notify?
It doesn't matter to my question, but during iteration N of the loop, the work being done by each thread is completely independent of the work being done at that time by the other threads. But during iteration N+1 of the loop, the work being done be each thread depends on the work that was done by all the threads during iteration N. That's why the main program has to wait on all the threads to complete an iteration before it can notify any of the threads to begin the next iteration. Were it not for that requirement, I wouldn't even need condition_variables. The threads could run asynchronously. The main program could just launch them all and wait for them all to complete via a join.
You can use a counter, which needs to be protected by mutex. Seit it to 0 before you start, and each thread increases it when it is done, so you need only a single object to check against which can be easily done with a condition variable.
if (DoneCount == ThreadCount)
// All threads done.
Can I get by with one condition_variable that each thread notifies? Or do I need a separate condition_variable for each thread to notify?
Either method works without any issues. Waiting for all of some set of things to happen can be accomplished simply by waiting for each of the things to happen successively in any order. You can use a shared condition variable or a different condition variable for each event.
Does anyone know of a condition variable class that allows notification of threads waiting for a condition to be notified in the order in which they started waiting?
I'm currently using the boost class condition_variable, but calling condition_variable::notify_one() wakes up a random thread, not the thread that first called condition_variable::wait(). I also tried adding thread ids to a queue before calling condition_variable::wait(), so that I can call condition_variable::notify_all() upon which all waiting threads wake up, check the queue and either wait again or proceed (only one thread, namely the thread first in queue). The problem is that calling notify_all() twice does not guarantee that all threads are waking up twice, thereby losing notifications. Any suggestions?
It is strange that you require threads to be woken in particular order and sounds suspicious about your design. Anyway idea is that you can have queue of condition variables (one per thread) and you would call notify_one() for one from top of the queue. In waiting thread you need to do additional logic to check that it was not sporadically interrupted from wait. Again sounds strange why you need thread to wake up in particular order and you may want to rethink your design.
Say the broadcasting thread broadcasts while only 3 threads are waiting and the 4th thread call pthread_cond_wait after the broadcasting thread is done with broadcast, will the 4th thread ever get out of the waiting condition. And how is the condition variable reset, so that the broadcasting thread can rebroadcast sometimes later to the waiting threads.
will the 4th thread ever get out of the waiting condition
No, not until there's another broadcast or signal.
And how is the condition variable reset, so that the broadcasting
thread can rebroadcast sometimes later to the waiting threads.
It's simplest to imagine that everything that a condition variable does, is synchronized under the mutex associated with the condition variable. So at the time you broadcast, everything waiting is (somehow) put into a state where it is trying to wake up and take the mutex. Then, the broadcasting thread releases the mutex. So it's not really the condition variable that's "reset" when you broadcast, it's the first three threads that are moved from waiting on the condition variable, to waiting on the mutex.
In order to wait on the condvar, your 4th thread must first acquire the mutex. This might happen before or after the first three threads manage to wake up and take the mutex, but it clearly happens after the broadcast, and so your 4th thread is not in "trying to wake up" state, it's in "waiting for a signal or broadcast" state.
Actually it's more complicated than that -- you don't actually have to hold the mutex in order to broadcast a condition variable. So condition variables must include some additional internal synchronization (I don't know the specific details on linux), to make sure that all threads waiting before the broadcast get their state changed as a single operation.
Normally you might as well hold the mutex to broadcast, though, because you broadcast when you've just changed something that waiters want to see, and whatever that thing is that's looked at from lots of threads, is synchronized using the mutex. And there are a couple of awkward situations that you can avoid by always doing it that way.
will the 4th thread ever get out of the waiting condition.
No, not unless the condition variable is signalled while thread 4 is waiting.
The man page explains:
The pthread_cond_broadcast() call unblocks all threads currently blocked on the specified condition variable cond.
The pthread_cond_signal() and pthread_cond_broadcast() functions have no effect if there are no threads currently blocked on cond.
I am looking for a C/C++ implementation of a multi threaded job dispatcher.
Boss thread (the main function) reads the job (eg executing msgrcv in a while(1) loop).
The boss reads the new job and depending on the destination dispatches the job to the
corresponding thread. The worker thread executes the job.
I don't have the time to build it from scratch, I am looking a ready solution.
UPDATE: I cannot use boost. It must be in pthreads (Linux)
Your simplest option is to have the worker threads waiting on a condition variable which gets signalled when a job comes in for them to read.
You would need a mutex that gets locked whilst you check the condition. When you wait on the condition variable it automatically unlocks the associated mutex until the condition gets signalled at which point your thread will have it. You should check your condition again.
You could have one condition variable for each queue or one for all the threads, it depends on how you are scaled.
Sound like you're after a thread pool. One can be found here (it requires boost). I'm sure Googling for "thread pool" or something similar will yield other posibilities.
I have a system where my singleton class spawns a thread to do a calculation. If the user requests another calculation while another calculation is still running, I want it to tear down the existing thread and start a new one. But, it should wait for the first thread to exit completely before proceeding. I have all the tear down working but I seem to have an issue with making sure that only one thread runs. My approach is for the StartCalculation function to call mutex->Lock(). And the thread in the destructor releases the lock. It's not working. Am I right in assuming that if Lock() can't get the lock, it spins and keeps trying to reacquire the lock? Can this Lock() be called from my main application thread? Any ideas is helpful. Maybe wxMutex locks are the right mechanism for this.
To wait for a thread you need to create it joinable and simply use wxThread::Wait(). However I agree with the remark above: this is not something you'd normally do at all and definitely not from the main GUI thread as you should never block in it because this freezes the UI.
Consider using a message queue to simply tell the existing thread about the new task it needs to perform instead.