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.
Related
I'm tryng to do the Dining philosophers, and in my code, after a thread drop the stick, they also send a broadcast to all thread waiting in the while loop, to move foward, but apparently this is not happening and I don't know way
https://github.com/lucizzz/Philosophers/blob/main/dinning.c
Your code has a lot of bugs, but the most fundamental one is that you access shared state without holding the mutex that protects that state. For example, the while loop in routine_1 tests the stick array without holding the mutex. It even calls pthread_cond_wait without holding the mutex.
This is wrong for many reasons, but the most obvious is this -- what if the while loop decides to call pthread_cond_wait, but then before you call pthread_cond_wait, the thread holding the resources releases it. Now, you are calling pthread_cond_wait to wait for something that has already happened -- you will be waiting forever.
You must hold the mutex both when you decide whether to call pthread_cond_wait and when you actually do call pthread_cond_wait or your code will wait forever if a thread releases the resource before you were able to wait for it.
Fundamentally, the whole point of condition variables is to provide an atomic "unlock and wait" operation to avoid this race condition. But your code doesn't use the mutexes correctly.
I'm trying to wrap my head around pthread condition variables.
I've seen some code examples that use pthread_cond_wait and pthread_cond_signal and all of them look like this:
while (condition)
{
// Assume that the mutex is locked before the following call
pthread_cond_wait(&cond, &mutex);
}
Is there a reason for using a while loop on the condition? why not just use a single if statement?
Spurious wakeups.
See Why does pthread_cond_wait have spurious wakeups? and also https://en.wikipedia.org/wiki/Spurious_wakeup:
Spurious wakeup describes a complication in the use of condition variables as provided by certain multithreading APIs such as POSIX
Threads and the Windows API.
Even after a condition variable appears to have been signaled from a
waiting thread's point of view, the condition that was awaited may
still be false. One of the reasons for this is a spurious wakeup; that
is, a thread might be awoken from its waiting state even though no
thread signaled the condition variable. For correctness it is
necessary, then, to verify that the condition is indeed true after the
thread has finished waiting. Because spurious wakeup can happen
repeatedly, this is achieved by waiting inside a loop that terminates
when the condition is true ...
I believe this is because threads may be spuriously woken up before the condition is met. Man, talk about "gotcha's".
From the Open Group documentation:
"Spurious wakeups from the pthread_cond_wait() or pthread_cond_timedwait() functions may occur."
Source:
http://pubs.opengroup.org/onlinepubs/007908775/xsh/pthread_cond_wait.html
Is there a reason for using a while loop on the condition? why not just use a single if statement?
The idea behind condition variables is to suspend thread execution until a given condition is satisfied. The condition is not built into the variable, however -- it must be provided by the programmer.
If the relevant condition is already satisfied, then there is no need to suspend operation. The key here, however, is that when the thread resumes, the condition might still not be satisfied, either because something changed between the condition variable being signaled and the thread being able to proceed, or because the thread awoke spurriously (this is allowed to happen, though it rarely does). The program therefore checks the condition again upon every wakeup to see whether it must resume waiting.
Scenario 1: release mutex then wait
Scenario 2: wait and then release mutex
Trying to understand conceptually what it does.
If the mutex were released before the calling thread is considered "blocked" on the condition variable, then another thread could lock the mutex, change the state that the predicate is based on, and call pthread_cond_signal without the waiting thread ever waking up (since it's not yet blocked). That's the problem.
Scenario 2, waiting then releasing the mutex, is internally how any real-world implementation has to work, since there's no such thing as an atomic implementation of the necessary behavior. But from the application's perspective, there's no way to observe the thread being part of the blocked set without the mutex also being released, so in the sense of the "abstract machine", it's atomic.
Edit: To go into more detail, the real-world implementation of a condition variable wait generally looks like:
Modify some internal state of the condition variable object such that the caller is considered to be part of the blocked set for it.
Unlock the mutex.
Perform a blocking wait operation, with the special property that it will return immediately if the state of the condition variable object from step 1 has changed due to a signal from any other thread.
Thus, the act of "blocking" is split between two steps, one of which happens before the mutex is unlocked (gaining membership in the blocked set) and the other of which happens after the mutex is unlocked (possibly sleeping and yielding control to other threads). It's this split that's able to make the "condition wait" operation "atomic" in the abstract machine.
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.
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.