I'm curious whether anyone has used something like:
pthread_mutex_lock(&ctx->processing_pipeline.feeder_safe_point_mutex);
while(!ctx->processing_pipeline.feeder_safe_point)
pthread_cond_wait(&ctx->processing_pipeline.feeder_safe_point_cv, &ctx->processing_pipeline.feeder_safe_point_mutex);
pthread_mutex_unlock(&ctx->processing_pipeline.feeder_safe_point_mutex);
... when waiting on a condvar.
The idea is that the feeder_safe_point int variable will be set to 1 when the event is completed and then the waiting thread will be woken up.
Also, what is the recommended way to use condvars to serialise the execution of multiple threads
Yes, that is exactly how you should use a pthreads condition variable. ctx->processing_pipeline.feeder_safe_point should also only be modified with ctx->processing_pipeline.feeder_safe_point_mutex locked.
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 want to implement a mutex lock.
From my understanding, mutex.lock() should work like
1) check lock owner
2) if lock is owned, put thread in waiting queue
3) suspend this thread until another thread send a wait up signal
However, there is nothing like pthread_suspend(), then how do I do suspend?
I found someone saying use pthread_con_wait(), but seems if I want to use that function, I have to set up a pthread_mutex lock first, which it doesn't make sense to use pthread_mutex inside my mutex.
Well, if my understanding of mutex is wrong, please correct me.
Thanks.
Mutexes, locks, and wait conditions are all different, distinct things. You need a mutex variable in order to implement both a lock and a wait condition.
A lock is a simple mechanism that prevents more than one thread from executing the same code at once by making all by one thread wait for the lock to become unlocked.
A wait condition is a slightly more complex structure that allows a thread to monitor a condition (usually a boolean flag) and only wake up when the flag has changed favourably.
In both cases, when a thread blocks (i.e. sleeps), the operating system's scheduling primitives automatically take care of descheduling the thread and using the available computing time elsewhere. Thread and task scheduling is not something you would normally have to worry about manually.
You can only make things that are at least as complex as the simplest pieces you have. If the simplest pieces you have are mutexes, then you can't make mutexes from the pieces you have. You can only make things at least as complex as a mutex or more so. If you have any pieces simpler than a mutex, tell us what they are, and we can tell you how to make a mutex out of them.
I suppose, if you want, you can make your own mutex out of pthread mutexes and condition variables. I'm not sure what the point is, but it's trivial to do. As you noted, you can use pthread_cond_wait to wait on your own kind of mutex.
The reason the pthreads standard gives you a mutex is because it's about the most flexible of the possible synchronization primitives.
mutex.lock() should work like:
1) check lock owner
2) if lock is owned, put thread in waiting queue
3) suspend this thread until THE THREAD THAT OWNS THE LOCK sends a wake up signal. No other thread can release the lock.
These steps should be performed as an atomic operation so that the correct behaviour is followed for all threads acquiring/releasing the mutex, no matter how such calls may be interrupted and reentered from other threads.
'However, there is nothing like pthread_suspend(), then how do I do suspend?' - usually, you don't. The OS kernel provides synchronization primitives that can block threads that should not run on. To implement a 'suspend' in user-space, you can only spin-wait - something that is a good strategy in a few cases, (underloaded multi-core box where the lock is only held for a very short time), but certainly not all, (and can lead to spectacularly disastrous livelocks across whole clusters of machines).
If you want a mutex, use an OS mutex - that's what any cross-platform lib. will do.
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.
My daemon initializes itself in four different threads before it starts doing its things. Right now I use a counter which is incremented when a thread is started and decremented when it is finished. When the counter hits 0 I call the initialization finished callback.
Is this the preferred way to do it, or are there better ways? I'm using POSIX threads (pthread) and I just run a while cycle to wait for the counter to hit 0.
Edit: pthread_barrier_* functions are not available on my platform although they do seem to be the best choice.
Edit 2: Not all threads exit. Some initialize and then listen to events. Basically the thread needs to say, "I'm done initializing".
A barrier is what you need. They were created for that, when you need to "meet up" at certain points before continuing. See pthread_barrier_*
Rather than spinning, use the pthread mutex/condvar primitives. I'd suggest a single mutex to protect both the count of threads outstanding, and the condvar.
The main loop looks like this:
acquire mutex
count=N_THREADS;
start your N threads
while (1) {
if (count==0) break;
cond_wait(condvar);
}
release mutex
And when each thread is ready it would do something like this:
acquire mutex
count--
cond_signal(condvar)
release mutex
(EDIT: I have assumed that the threads are to keep going once they have done their initialisation stuff. If they are to finish, use pthread_join as others have said.)
pthread_join is the preferred way to wait for pthreads.
That sounds ... weird. Shouldn't you just be using pthread_join() to wait for the threads to complete? Maybe I don't understand the question.
As Klas Lindbäck pointed out in his answer, joining threads is a preferred way to go.
In case your threads are not exiting (i.e. are part of the reusable pool etc.), the logic sounds good. The only thing is that using counter without any synchronisation is dangerous. You have to use either mutex with condition or atomic integer. I'd recommend using mutex + condition if you don't want to spin on atomic counter in the thread that waits for initialisation to finish.
So, what happens if one thread finishes initialization before any of the others begin?
So one way to do it
initialize an atomic counter to 0
when each thread is done with init, increment counter and retrieve the value atomically. If you use GCC, you can use __sync_add_and_fetch()
If the retrieved counter value < N_threads, block on a pthread condition variable.
If the retrieved counter value == N_threads, init phase is done, signal the condition and continue.
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.