One condition variable, multiple mutexes - multithreading

I was watching Operating system course part 2 lecture 2 video 17. In this lecture she mentioned that the data-structure of condition variable contains mutex reference and list of waiting threads.
I want to know if it is possible to use the same condition with different mutexes?
For example: I have 2 wait statements
wait(mutex1, condition_A)
wait(mutex2, condition_A) //condition is the same in both
If the answer to the above question is yes, then will these two statements create two condition variables or one? Note: Lecture mentioned only one mutex reference.

I guess it depends on the implementation.
POSIX says:
When a thread waits on a condition variable, having specified a
particular mutex to either the pthread_cond_timedwait() or the
pthread_cond_wait() operation, a dynamic binding is formed between
that mutex and condition variable that remains in effect as long as at
least one thread is blocked on the condition variable. During this
time, the effect of an attempt by any thread to wait on that condition
variable using a different mutex is undefined. Once all waiting
threads have been unblocked (as by the pthread_cond_broadcast()
operation), the next wait operation on that condition variable shall
form a new dynamic binding with the mutex specified by that wait
operation.
So you can you the same condition variable with difference mutexes, but not at the same time.
With regards to C++, cppreference.com says:
Calling this function if lock.mutex() is not the same mutex as the one
used by all other threads that are currently waiting on the same
condition variable is undefined behavior.
So it seems to have the same requirements as POSIX condition variables.

Related

How to wait on any condition variable?

pthread_cond_wait allows us to wait until a condition variable gets signaled.
However, is there any chance to wait until any of two condition variables gets signaled?
The reason I’m asking is that I have the following situation: I have 42 threads and two possible predicates under which these threads may continue they work. They may continue their work if ANY of these two predicates is fulfilled.
But, but, the problem is, that when one of these predicates is fulfilled, then only one thread, and a specific thread, not any thread, can continue working. If the other is fulfilled, then ALL threads should be resumed.
So, my idea was to have one condition variable that is broadcasted whenever the second pred is fulfilled… and 42 more condition variables, each associated with one of the threads. The appropriate one of them is to be signaled whenever the first pred is fulfilled.
But this requires the threads to wake whenever ANY of a given set of cond variables is signaled… Any chance to achieve this?
No, you can only wait on a single condition variable.
However, that is fine. When a thread is woken from a pthread_cond_wait(), it must check that the predicate it is waiting for is actually true anyway - this is because waits on condition variables are allowed to be woken at any time (known as a "spurious wakeup").
So, since your threads must check on whether they are allowed to proceed when pthread_cond_wait() returns, you can just use a single condition variable paired with pthread_cond_broadcast(). The threads themselves determine (based on examining the shared state protected by the mutex) whether they are individually allowed to proceed or should continue waiting. So, something like this:
pthread_mutex_lock(&lock);
while (!this_thread_can_proceed(state) && !all_threads_can_proceed(state))
pthread_cond_wait(&cond, &lock);
Alternatively, you are allowed to wait on multiple condition variables using the same mutex (the converse is not allowed), so you can have every thread wait on its own condition variable, and then the waking thread either signals a single condition variable, or loops over the set signalling them all, depending on which predicate it has fulfilled.
Which one of these solutions will perform better depends on the balance between "all threads" and "one thread" wakeups in your application.

What is the name of this synchronisation method?

I have a special programming construct that allows threads to wait until another thread releases all waiting threads at once.
Each thread can register itself to wait for an external event that can be triggered by another thread (for example one that listens for user input). Once that event occurs all threads can continue and are immediately deregistered.
My question is: What is a construct like this called?
At first I thought of mutex, but as far as i know a mutex is a construct that only allows one thread to run at once (See this link https://www.quora.com/Semaphore-vs-mutex-vs-monitor-What-are-the-differences).
To me this construct sounds like a phaser in java, but my construct does not have a counting logic, so I was wondering what the correct wording is.
Relevant Java and C# classes have the word "barrier" in them, so that might be what you want.
The correct answer is: this is mostly like a condition variable of a monitor. Quoting Wikipedia:
A condition variable essentially is a container of threads that are
waiting for a certain condition. Monitors provide a mechanism for
threads to temporarily give up exclusive access in order to wait for
some condition to be met, before regaining exclusive access and
resuming their task.
An example implementation of this is Java's wait and notifyAll.

How can many threads wait on a condition variable if we place a mutex before it?

pthread_cond_broadcast is used to wake up several threads waiting on a condition variable. But, at the same time it is also said that we should place a mutex before the condition variable to avoid race conditions.
So, if a mutex is there, and one thread already holds it and thus waits on the variable, how can any other thread hold the same mutex (to enter to the waiting part)?
When a thread calls pthread_cond_wait() it needs to hold the associated mutex. The API will release the mutex while it blocks the thread. Once the API decides the thread needs to be released, it will acquire the mutex before returning from the API.
Holding the mutex is required because checking the condition then calling pthread_cond_wait() isn't an atomic operation. The mutex (and the proper use of the mutex) prevents the thread from missing the condition becoming true in the short period between checking it and calling the wait.
But the short answer to the specific question (how can another thread obtain the mutex) is that while the thread is blocked in pthread_cond_wait(), the mutex is not held.

Condition variables: used only to simulate monitors?

I'm reading "Multithreaded, Parallel, and Distributed Programming" by Gregory Andrews, and in this book the author mentions that he'll show how to use locks "in combination with condition variables to simulate monitors".
I have also heard several times that "mutex lock + condition variable" is a common pattern in programs using Posix threads.
So my question is: are there other common uses of condition variables besides this (using them in combination with locks to simulate monitors"? If so, what would be a simple example of usage?
A monitor enables two different things:
mutal exclusion - at most one thread may own the monitor at any given time
cooperation - the thread owning the monitor can opt to wait until it is awakened by a cooperating thread via a notification sent through the monitor
The Posix threading library separates these two concerns into two different objects:
mutual exclusion is accomplished using a mutex
cooperation is accomplished using a condition variable
It is assumed that the cooperation is with regard to some state shared between threads. This state is expected to be protected by a mutex. Thus, the basic wait operation takes two arguments:
a condition variable to wait for notification (signaling) on
the mutex protecting the shared state
When a thread waits on a condition variable using a mutex, the mutex is released and the thread is put to sleep. When the thread awakens, it will reacquire the mutex before continuing.
Signaling (notify one thread) or broadcasting (notify all threads) a condition variable does not require a mutex.
Condition variables are intended solely for this use. It is possible to use them as a "sleep for a while and release this mutex while you sleep" command by using a private condition variable that is never signaled and a timed wait (pthread_cond_timedwait()).
A condition variable is always used in conjunction with a mutex. For example, when you call pthread_cond_wait, you must specify not only the condition variable itself, but also the mutex you're using with it.

Conditional Variable vs Semaphore

When to use a semaphore and when to use a conditional variable?
Locks are used for mutual exclusion. When you want to ensure that a piece of code is atomic, put a lock around it. You could theoretically use a binary semaphore to do this, but that's a special case.
Semaphores and condition variables build on top of the mutual exclusion provide by locks and are used for providing synchronized access to shared resources. They can be used for similar purposes.
A condition variable is generally used to avoid busy waiting (looping repeatedly while checking a condition) while waiting for a resource to become available. For instance, if you have a thread (or multiple threads) that can't continue onward until a queue is empty, the busy waiting approach would be to just doing something like:
//pseudocode
while(!queue.empty())
{
sleep(1);
}
The problem with this is that you're wasting processor time by having this thread repeatedly check the condition. Why not instead have a synchronization variable that can be signaled to tell the thread that the resource is available?
//pseudocode
syncVar.lock.acquire();
while(!queue.empty())
{
syncVar.wait();
}
//do stuff with queue
syncVar.lock.release();
Presumably, you'll have a thread somewhere else that is pulling things out of the queue. When the queue is empty, it can call syncVar.signal() to wake up a random thread that is sitting asleep on syncVar.wait() (or there's usually also a signalAll() or broadcast() method to wake up all the threads that are waiting).
I generally use synchronization variables like this when I have one or more threads waiting on a single particular condition (e.g. for the queue to be empty).
Semaphores can be used similarly, but I think they're better used when you have a shared resource that can be available and unavailable based on some integer number of available things. Semaphores are good for producer/consumer situations where producers are allocating resources and consumers are consuming them.
Think about if you had a soda vending machine. There's only one soda machine and it's a shared resource. You have one thread that's a vendor (producer) who is responsible for keeping the machine stocked and N threads that are buyers (consumers) who want to get sodas out of the machine. The number of sodas in the machine is the integer value that will drive our semaphore.
Every buyer (consumer) thread that comes to the soda machine calls the semaphore down() method to take a soda. This will grab a soda from the machine and decrement the count of available sodas by 1. If there are sodas available, the code will just keep running past the down() statement without a problem. If no sodas are available, the thread will sleep here waiting to be notified of when soda is made available again (when there are more sodas in the machine).
The vendor (producer) thread would essentially be waiting for the soda machine to be empty. The vendor gets notified when the last soda is taken from the machine (and one or more consumers are potentially waiting to get sodas out). The vendor would restock the soda machine with the semaphore up() method, the available number of sodas would be incremented each time and thereby the waiting consumer threads would get notified that more soda is available.
The wait() and signal() methods of a synchronization variable tend to be hidden within the down() and up() operations of the semaphore.
Certainly there's overlap between the two choices. There are many scenarios where a semaphore or a condition variable (or set of condition variables) could both serve your purposes. Both semaphores and condition variables are associated with a lock object that they use to maintain mutual exclusion, but then they provide extra functionality on top of the lock for synchronizing thread execution. It's mostly up to you to figure out which one makes the most sense for your situation.
That's not necessarily the most technical description, but that's how it makes sense in my head.
Let's reveal what's under the hood.
Conditional variable is essentially a wait-queue, that supports blocking-wait and wakeup operations, i.e. you can put a thread into the wait-queue and set its state to BLOCK, and get a thread out from it and set its state to READY.
Note that to use a conditional variable, two other elements are needed:
a condition (typically implemented by checking a flag or a counter)
a mutex that protects the condition
The protocol then becomes,
acquire mutex
check condition
block and release mutex if condition is true, else release mutex
Semaphore is essentially a counter + a mutex + a wait queue. And it can be used as it is without external dependencies. You can use it either as a mutex or as a conditional variable.
Therefore, semaphore can be treated as a more sophisticated structure than conditional variable, while the latter is more lightweight and flexible.
Semaphores can be used to implement exclusive access to variables, however they are meant to be used for synchronization. Mutexes, on the other hand, have a semantics which is strictly related to mutual exclusion: only the process which locked the resource is allowed to unlock it.
Unfortunately you cannot implement synchronization with mutexes, that's why we have condition variables. Also notice that with condition variables you can unlock all the waiting threads in the same instant by using the broadcast unlocking. This cannot be done with semaphores.
semaphore and condition variables are very similar and are used mostly for the same purposes. However, there are minor differences that could make one preferable. For example, to implement barrier synchronization you would not be able to use a semaphore.But a condition variable is ideal.
Barrier synchronization is when you want all of your threads to wait until everyone has arrived at a certain part in the thread function. this can be implemented by having a static variable which is initially the value of total threads decremented by each thread when it reaches that barrier. this would mean we want each thread to sleep until the last one arrives.A semaphore would do the exact opposite! with a semaphore, each thread would keep running and the last thread (which will set semaphore value to 0) will go to sleep.
a condition variable on the other hand, is ideal. when each thread gets to the barrier we check if our static counter is zero. if not, we set the thread to sleep with the condition variable wait function. when the last thread arrives at the barrier, the counter value will be decremented to zero and this last thread will call the condition variable signal function which will wake up all the other threads!
I file condition variables under monitor synchronization. I've generally seen semaphores and monitors as two different synchronization styles. There are differences between the two in terms of how much state data is inherently kept and how you want to model code - but there really isn't any problem that can be solved by one but not the other.
I tend to code towards monitor form; in most languages I work in that comes down to mutexes, condition variables, and some backing state variables. But semaphores would do the job too.
semaphore need to know the count upfront for initialization. There is no such requirement for condition variables.
The the mutex and conditional variables are inherited from semaphore.
For mutex, the semaphore uses two states: 0, 1
For condition variables the semaphore uses counter.
They are like syntactic sugar
conditionalVar + mutex == semaphore

Resources