Condition Variable vs Semaphore example - c

I'm having a hard time solving this homework problem. Does calling x.signal() in one thread and later x.wait() in another thread produce a different result when x is a condition variable and when x is a semaphore?
My guess is that in this particular case it won't matter if x is a condition variable or a semaphore.
Thank you for help!

Semaphore has a state protected by atomic operations, meanwhile the condition variable (CV) does not have its own state and is not even protected (the usual assumption is that the program has its own, more complicated shared state than just an integer and thus needs to maintain it "manually").
The correct use of CV requires that both signal and wait operations are protected (surrounded by the associated mutex locking), otherwise the waiting thread may miss the signalling. So the program needs to ensure the proper locking sequence on CVs.
Meanwhile semaphore operations are hidden from developer, and the code is simpler and cannot go wrong in ways CVs can, but it also maintains very simple/small shared state with very specific operations.

Related

How to make a thread wait for multiple conditional signals from different threads?

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.

POSIX binary semaphore

How can I implement a binary semaphore using the POSIX counting semaphore API? I am using an unnamed semaphore and need to limit its count to 1. I believe I can't use a mutex because I need to be able to unlock from another thread.
If you actually want a semaphore that "absorbs" multiple posts without allowing multiple waits to succeed, and especially if you want to be strict about that, POSIX semaphores are not a good underlying promitive to use to implement it. The right set of primitives to implement it on top of is a mutex, a condition variable, and a bool protected by the mutex. When changing the bool from 0 to 1, you signal the condition variable.
With that said, what you're asking for is something of a smell; it inherently has ambiguous orderings. For example if threads A and B both post the semaphore one after another, and threads X and Y are both just starting to wait, it's possible with your non-counting semaphore that either both waits succeed or that only one does, depending on the order of execution: ABXY or AXBY (or other comparable permutation). Thus, the pattern is likely erroneous unless either there's only one thread that could possibly psot at any given time (in which case, why would it post more than once? maybe this is a non-issue) or ability to post is controlled by holding some sort of lock (again, in which case why would it post more than once?). So if you don't have a design flaw here, it's likely that just using a counting semaphore but not posting it more than once gives the behavior you want.
If that's not the case, then there's probably some other data associated with the semaphore that's not properly synchronized, and you're trying to use the semaphore like a condition variable for it. If that's the case, just put a proper mutex and condition variable around it and use them, and forget the semaphore.
One comment for addressing your specific situation:
I believe I can't use a mutex because I need to be able to unlock from another thread.
This becomes a non-issue if you use a combination of mutex and condition variable, because you don't keep the mutex locked while working. Instead, the fact that the combined system is in-use is part of the state protected by the mutex (e.g. the above-mentioned bool) and any thread that can obtain the mutex can change it (to return it to a released state).

What does GCC's Compare-And-Swap Guarantee on a Modern Processor

I would like to know what __sync_bool_compare_and_swap() guarantees in different scenarios
When only one thread accesses the data - I assume it would check the pointer, and swap it if it matches the value
But what if, Two processors, compare-and-swapped at the same time? What would happen?
What if a thread compare-and-swapped when another thread was setting the value?
What if a thread compare-and-swapped when a value is protected by a mutex
Assuming of course that there are only 2 threads that access any data concurrently...
The key point to understand is that this is done using specific CPU instructions that are able to write atomically.
If two threads compared and swapped, one of them will be able to do it first, the other will fail and will have to retry with the new value.
If the value is protected by mutex in both threads (assuming 2 threads), then anyway __sync_bool_compare_and_swap() would get called one at a time. If it was protected in only one thread, consider it as if it is not protected, i.e. mutex has no effect.

Can a process call "down" on two semaphores at once?

Let's say two semaphores are protecting a critical piece of code, and you only want a critical piece of code to execute if both of them are available. Is there a pattern for writing this?
In other words, is there a statement that reads, "If semaphore a and b are available, then run... otherwise sleep"?
The simplest way to implement this is to use a single pthread_mutex_t to protect some state, and a single pthread_cond_t to notify all threads when the state has changed. If you always broadcast on the condvar, then you will always wake all waiting threads. The threads can then perform arbitrarily complex tests and updates to the shared state.
Of course, this is not the most efficient solution since it potentially wakes threads when the state does not satisfy the condition they are waiting for (and they have to go back to sleep). It could also lead to starvation since a thread may always find itself at the back of the queue whenever it waits on the condvar, and never find an acceptable state when it awakens.
Without knowing more details of the problem you are trying to solve, it is hard to give an air tight answer.
pthreads does not allow you to acquire multiple locks/semaphores atomically; however, as pointed out by #Greg, you can avoid deadlock by assigning an order to the locks/semaphores, and having the threads always acquire them in that order. Of course, you have to know which locks you intend to acquire before you start to acquire any of them. It will not work if you cannot determine the next lock to acquire until you have acquired the current one, since you may be required to take a lock out of order. If you release all of the locks and start over, you may find the state has changed, requiring you to acquire a different set of locks, which could lead to livelock.

POSIX threads and global variables in C on Linux

If I have two threads and one global variable (one thread constantly loops to read the variable; the other constantly loops to write to it) would anything happen that shouldn't? (ex: exceptions, errors). If it, does what is a way to prevent this. I was reading about mutex locks and that they allow exclusive access to a variable to one thread. Does this mean that only that thread can read and write to it and no other?
Would anything happen that shouldn't?
It depends in part on the type of the variables. If the variable is, say, a string (long array of characters), then if the writer and the reader access it at the same time, it is completely undefined what the reader will see.
This is why mutexes and other coordinating mechanisms are provided by pthreads.
Does this mean that only that thread can read and write to it and no other?
Mutexes ensure that at most one thread that is using the mutex can have permission to proceed. All other threads using the same mutex will be held up until the first thread releases the mutex. Therefore, if the code is written properly, at any time, only one thread will be able to access the variable. If the code is not written properly, then:
one thread might access the variable without checking that it has permission to do so
one thread might acquire the mutex and never release it
one thread might destroy the mutex without notifying the other
None of these is desirable behaviour, but the mere existence of a mutex does not prevent any of these happening.
Nevertheless, your code could reasonably use a mutex carefully and then the access to the global variable would be properly controlled. While it has permission via the mutex, either thread could modify the variable, or just read the variable. Either will be safe from interference by the other thread.
Does this mean that only that thread can read and write to it and no other?
It means that only one thread can read or write to the global variable at a time.
The two threads will not race amongst themselves to access the global variable neither will they access it at the same time at any given point of time.
In short the access to the global variable is Synchronized.
First; In C/C++ unsynchronized read/write of variable does not generate any exceptions or system error, BUT it can generate application level errors -- mostly because you are unlikely to fully understand how the memory is accessed, and whether it is atomic unless you look at the generated assembler. A multi core CPU may likely create hard-to-debug race conditions when you access shared memory without synchronization.
Hence
Second; You should always use synchronization -- such as mutex locks -- when dealing with shared memory. A mutex lock is cheap; so it will not really impact performance if done right. Rule of thumb; keep the lcok for as short as possible, such as just for the duration of reading/incrementing/writing the shared memory.
However, from your description, it sounds like that one of your threads is doing nothing BUT waiting for the shared meory to change state before doing something -- that is a bad multi-threaded design which cost unnecessary CPU burn, so
Third; Look at using semaphores (sem_create/wait/post) for synchronization between your threads if you are trying to send a "message" from one thread to the other
As others already said, when communicating between threads through "normal" objects you have to take care of race conditions. Besides mutexes and other lock structures that are relatively heavy weight, the new C standard (C11) provides atomic types and operations that are guaranteed to be race-free. Most modern processors provide instructions for such types and many modern compilers (in particular gcc on linux) already provide their proper interfaces for such operations.
If the threads truly are only one producer and only one consumer, then (barring compiler bugs) then
1) marking the variable as volatile, and
2) making sure that it is correctly aligned, so as to avoid interleaved fetches and stores
will allow you to do this without locking.

Resources