This question follows from Breaking a condition variable deadlock. A number of threads may be waiting on a condition variable, I need to signal only a particular thread say thread 1 and kill it as it was a participant of a deadlock scenario. Is there a way i could signal just a partipular thread amoung the lot.
Would be gratefull for some help
thanks
An Edit; Respecting Nemo's comments. I understand this is a bad idea. But, is there a way to do it
You can use deferred cancellation points. In your threads, use pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldstate); (this is the default, but it never hurts to be explicit); then disable cancellation with pthread_setcancelstate except for over the condition variable waits you want to be cancellable. Be sure that you use pthread_cleanup_push to set up cancellation cleanup handlers; this will NOT play nicely with RAII.
And now you can just pthread_cancel your thread. Cancellation cleanup handlers are executed, in reverse order of registration, TLS data destructors are called, and the thread exits (without returning from the condition variable wait).
Of course, this is a rather ugly design. Ideally you should avoid deadlocking at all; if that isn't possible, if it were me, I would arrange for only one thread to ever block on a single cvar at a time, and build a higher level (explicit waiter list) construct based on these cvars in order to handle multiple waiters, while still allowing for threads to be individually addressable.
Just write code to do exactly what you need. There's no shortcut since condition variables don't provide this behavior. So just write it. There's nothing difficult about it. For example, you could set a special flag, wake all threads blocked on the condition variable, and then code the threads to check the flag to see if there's supposed to go back to sleep or not.
Related
Does the pthread library (in C/C++) have a function like pthread_cond_wait(&cond, &mutex) that can wait for conditional signals (such as pthread_cond_signal(&cond1), pthread_cond_signal(&cond2) and so on...) from multiple different threads?
If this is not possible, then what is the most effective way to implement this strategy?
Does the pthread library (in C/C++) have a function like pthread_cond_wait(&cond, &mutex) that can wait for conditional signals (such as pthread_cond_signal(&cond1), pthread_cond_signal(&cond2) and so on...) from multiple different threads?
What you're describing is not about different threads -- pthread_cond_wait() / pthread_cond_signal() already handle that just fine, as indeed they need to do to serve their intended purpose. If a given thread is waiting on condition variable cond1 then it can be awakened by any thread that signals or broadcasts to cond1. And ultimately, that may be the direction you want to go.
But what you actually asked about is whether a thread can block on multiple condition variables at the same time, and no, pthreads makes no provision for that. Nor would that make sense for the usage model for which condition variables are designed.
I suspect that you are looking at CV waiting / signaling as purely a notification mechanism, but this is altogether the wrong view. A thread uses a condition variable to suspend execution until another thread performs work that causes some condition to be satisfied (otherwise, why wait at all)? That's normally a condition that can be evaluated based on data protected by the associated mutex, so that the prospective waiting thread can
avoid data races involving the data in question (by locking the mutex at the beginning, before accessing them, and relying on other threads to do the same);
be assured (because it holds the mutex locked) that the condition will not change unexpectedly after it is evaluated;
avoid waiting at all when the condition is already satisfied;
verify when it resumes from waiting that the condition in fact is satisfied (MANDATORY).
When the condition indeed is satisfied, the thread moves on with whatever action it wanted to perform that required the condition to be satisfied. That's important. The thread waited to be able to perform a specific thing, so what does it matter if the conditions are then right for performing some other thing, too? And if it wants to perform that other thing next, then it can do it without waiting if the conditions for that still hold.
On the side of the signal sender, you should not think about it as notifying a specific thread. Instead, it is announcing to any thread that cares that something it is presently interested in may have changed.
I appreciate that this is all fairly abstract. Multithreaded programming is challenging. But this is why students are given exercises such as producer / consumer problems or the Dining Philosophers problem. Learn and apply the correct idioms for CV usage. Think about what they are achieving for you. It will become clearer in time.
In one of my courses, my professor asks us to implement a small program that spawns 5 threads and use a mutex to check if it's the threads respective turn. However, he also requested that we use a condition variable to avoid busy waiting for their turn.
From first glance this doesn't make much sense to me, because we cannot guarantee that any signal is going to wake up the correct thread. It seems like this is bound to be a deadlock unless the infinitely unlikely scenario occurs that the correct sleeping thread is woken up every time. Am I missing something?
Your professor gave you the necessary information to complete the task.
From first glance this doesn't make much sense to me, because we cannot guarantee that any signal is going to wake up the correct thread.
Yes, the setup you are thinking of is used when you don't care which thread is waked up, e.g. when you have a worker pool and you just need a free thread, any free thread to assign the work to.
But if you think about it you can see you can create setups with locks and condition variables that result in your desired behavior, i.e. waking up a specific thread.
Hint: a condition variable has notify_all
Hint: or, alternatively, you can have more than 1 condition variable.
Think a bit about it and try different things.
I have a situation where thread 1 is waiting on a condition variable A, which should be woken up by thread 2. Now thread 2 is waiting on a condition variable B , which should be woken up by thread 1. In the scenario I am using the condition variable, I cannot avoid such a deadlock situation. I detect cycle(deadlock) and terminate one of the threads which is a participant in the deadlock.
Now, what I am not sure is how to simply terminate a thread say thread 1 which is waiting on a condition variable.
Would be grateful for some pointers.
Thanks
Condition variables aren't like mutexes. By that I mean they aren't only usable by a single thread controlling them. The mutex that protects the condition variable is treated that way but that's only locked for short periods of time, unlocked manually by a thread after kicking (signalling) the condition variable, and automatically by a thread waiting for such a kick.
You can have a totally separate thread (like your deadlock detector, let's call it thread 3) simply kick one of the condition variables and it will wake up the thread waiting for it.
The usual use case for condition variables is for threads to wait for the kick then check to ensure you have work anyway (don't assume there is work simply because the variable was kicked). That's to take care of spurious wake-ups.
One possibility is to have a "global" deadlock_occurred flag which thread 3 sets when it detects deadlock, then also have thread 3 kick all the condition variables.
The first thing that threads 1 and 2 should do after being woken, should be to check that flag and take appropriate action (probably exit the thread).
You'll find you get into a lot less deadlock-type trouble if you architect your applications so that threads are responsible for their own lifetime. It's too easy to externally kill threads when they're not in a state amenable to being terminated. Don't get me wrong, there are other ways to handle it (such as with cancel points), but my tried and tested solution is by far the easiest I've ever found.
I have encountered a problem while implementing wait and signal conditions on multiple threads.
A thread needs to lock a mutex and wait on a condition variable until some other thread signals it. In the meanwhile, another thread locks the same mutex and waits on the same condition variable. Now, the thread which is running concurrently throughout the process signals the condition variable but I want only the first thread that is waiting must be signalled and not the others.
If two threads wait on the same condition variable, they must be prepared to handle the same conditions, or you must carefully construct your program so they are never waiting on the condition variable at the same time.
Why does this notification have to be handled by the first thread and not the second?
You may be better off with two separate condition variables.
Use pthread_cond_signal() to wake up one of the threads.
However, more than one might be awoken; this is termed spurious wakeup. You need a variable to track your application state, as described in the manual page linked above.
Your requirement is impossible. You say "... I want only the first thread that is waiting must be signalled and not the others." But condition variables never, ever provide any way to ensure a thread isn't signaled. So if you have a requirement that a thread must not be signaled, you cannot use condition variables.
You must always use a condition variable like this:
while(NotSupposedToRun)
pthread_cond_wait(...);
So if the thread wakes up when it's not supposed to, the while is still false and the thread just goes back to sleep. This is mandatory because POSIX does not ever provide any guarantee that a thread won't be woken. An implementation is perfectly free to implement pthread_cond_signal as a call to pthread_cond_broadcast and unblock all threads on every signal if it wants to.
Because condition variables are stateless, the implementation never knows whether a thread is supposed to be woken or not for sure. It is your job to call pthread_cond_wait always, and only, when a thread should not be running.
See
http://en.wikipedia.org/wiki/Spurious_wakeup
for more details.
If you cannot precisely specify the wakeup conditions for each thread in a while loop like the one above, you should not be using condition variables.
My current understanding of condition variables is that all blocked (waiting) threads are inserted into a basic FIFO queue, the first item of which is awakened when signal() is called.
Is there any way to modify this queue (or create a new structure) to perform as a priority queue instead? I've been thinking about it for a while, but most solutions I have end up being hampered by the existing queue structure inherent to C.V.'s and mutexes.
Thanks!
I think you should rethink what you're trying to do. If you're trying to optimize your performance, you're probably barking up the wrong tree.
pthread_cond_signal() isn't even guaranteed to unblock exactly one thread -- it's guaranteed to unblock at least one thread, so your code better be able to handle the situation where multiple threads are unblocked simultaneously. The typical way to do this is for each thread to re-check the condition after becoming unblocked, and, if false, return to waiting again.
You could implement some sort of scheme where you kept your own priority queue of threads waiting, and each thread added itself to that queue immediately before it was to begin waiting, and then it would check the queue when unblocking, but this would add a lot of complexity and a lot of potential for serious problems (race conditions, deadlocks, etc.). It was also add a non-trivial amount of overhead.
Also, what happens if a higher-priority thread starts waiting on a condition variable at the same moment that condition variable is being signalled? Who gets unblocked, the newly arrived high-priority thread or the former highest priority thread?
The order that threads get unblocked in is entirely dependent on the kernel's thread scheduler, so you are at its mercy. I wouldn't even assume FIFO ordering, either.
Since condition variables are basically just a barrier and you have no control over the queue of waiting threads there's no real way to apply priorities. It's invalid to assume waiting threads will act in a FIFO manner.
With a combination of atomics, additional condition variables, and pre-knowledge of the threads/priorities involved you could construct a solution where a signaled thread will re-signal the master CV and then re-block on a priority CV but it certainly wouldn't be a generic solution. That's also off the top of my head so might also have some other flaw.
It's the scheduler that determines which thread will run. You can look at pthread_setschedparam and pthread_getschedparam and fiddle with the policies (SCHED_OTHER, SCHED_FIFO, or SCHED_RR) and the priorities. But it probably won't get you to where I suspect you want to go.
It sounds as if you want to make something predictable from the inherently non-deterministic. As Andrew notes you might hack something but my guess is that this will lead to heartache or a lot code you will hate yourself for writing in six months (or both).