I was wondering if there was a way to implement semaphore in C++ (or C#), any libraries that'd help. I tried using OpenMP but I had no way of actually blocking threads, instead I had to busy wait on 'em which lead to deadlocks if/when I hadn't enough number of threads. So First I'm looking for a some library that would let me block/spawn/kill my threads.
Secondly, are there any libraries out there that already implement semaphores?
And finally, when I was introduced to the context of semaphores I found it very useful (maybe I'm wrong?) but I don't see many libraries (if at all) implementing it. I'm familiar with OpenMP, looked around Intel's TBB, C# threads. But in none of these I don't see semaphores explicitly. So are semaphores not as practical as I think? Or is it that they're hard to implement? Or is it me not being aware?
P.S.
Can semaphores be implemented cross-platform? Since they're probably related to OS.

- 7,534
- 16
- 61
- 101
-
1There's `omp_set_lock`/ `omp_unset_lock` in OpenMP, and pthread has support for mutex (TBB almost certainly has them too, though I've never worked with that). Lastly, if you don't object to Boost, you can use the semaphore and mutex implementations in there. All of the forementioned are cross-platform (layering OS-specific functions). In general, you cannot implement a non-busy synchronisation without OS-dependent code, but that's exactly what those libraries are for. – Damon May 14 '11 at 09:00
-
@Damon I'm familiar with OMP locks, but if you investigate 'em a little you'd notice a thread cannot unset a lock it did not set. – atoMerz May 14 '11 at 09:02
-
That is correct, but even with this limitation, it nevertheless provides you with the basic functionality necessary to implement any other synchronisation. Though of course the other libs that I mentioned are a lot more user-friendly in that respect. – Damon May 14 '11 at 10:00
4 Answers
Are there any libraries out there that already implement this?
For C++ there are multiple multithreading libraries, which provide Semaphore implementations:
Also, You can also implement Semaphores using Boost. Check this out.
-
thank you, are any of libraries preferred? Preferred as in easier to learn and use. I heard that you have to write too much code with posix to start a thread. – atoMerz May 14 '11 at 09:05
-
@AtoMerZ: I would suggest using POSIX for multiple reasons. It offers portability & wide support in case you face problems. As far as writing too much code, its just that you get more flexibility on the configuration or threading model you would want to implement. – Alok Save May 14 '11 at 09:09
-
does POSIX also allow manually blocking threads/processes? If so then I think this is what I was looking for. – atoMerz May 14 '11 at 10:41
-
@AtoMerZ: Yes, POSIX provides mutexes and semaphores for thread and process synchronization. – Alok Save May 14 '11 at 10:56
First advice use boost. All the hard work has been done.
If you want to see how it is implemented it should look like this (though this is a rough sketch I am sure with some research ti can be optimized). Basically a semaphore is built from three things:
- A count
- A condition variable (that provides the suspend)
- A mutex which provides the exclusiveness to modify the count and wait on the condition.
Here is the simple version:
#include <pthread.h>
// Need an exception safe locking class.
struct MutexLocker
{
MutexLocker(pthread_mutex_t& m) :mutex(m)
{ if (pthread_mutex_lock(&mutex) != 0) {throw int(1); }}
~MutexLocker()
{ if (pthread_mutex_unlock(&mutex) != 0) {throw int(1); }}
private:
pthread_mutex_t& mutex;
};
class Semaphore
{
public:
Semaphore(int initCount = 0)
: count(initCount)
, waitCount(0)
{
if (pthread_mutex_init(&mutex, NULL) != 0)
{ throw int(1);
}
if (pthread_cond_init(&cond, NULL) != 0)
{ pthread_mutex_destroy(&mutex);
throw int(2);
}
}
void wait()
{
MutexLocker locker(mutex);
while(count == 0)
{
++waitCount;
if (pthread_cond_wait(&cond, &mutex) != 0)
{ throw int(2);
}
// A call to pthread_cond_wait() unlocks the mutex and suspends the thread.
// It does not busy wait the thread is suspended.
//
// When a condition variable receives apthread_cond_signal() a random thread
// is un-suspended. But it is not released from the call to wait
// until the mutex can be reacquired by the thread.
//
// Thus we get here only after the mutex has been locked.
//
// You need to use a while loop above because of this potential situation.
// Thread A: Suspended waiting on condition variable.
// Thread B: Working somewhere else.
// Thread C: calls signal() below (incrementing count to 1)
// This results in A being awakened but it can not exit pthread_cond_wait()
// until it requires the mutex with a lock. While it tries to
// do that thread B finishes what it was doing and calls wait()
// Thread C has incremented the count to 1 so thread B does not
// suspend but decrements the count to zero and exits.
// Thread B now aquires the mutex but the count has been decremented to
// zero so it must immediately re-suspend on the condition variable.
// Note a thread will not be released from wait until
// it receives a signal and the mustex lock can be re-established.
--waitCount;
}
--count;
}
void signal()
{
// You could optimize this part with interlocked increment.
MutexLocker locker(mutex);
++count;
// This Comment based on using `interlocked increment` rather than mutex.
//
// As this part does not modify anything you don;t actually need the lock.
// Potentially this will release more threads than you need (as you don't
// have exclusivity on reading waitCount but that will not matter as the
// wait() method does and any extra woken threads will be put back to sleep.
// If there are any waiting threads let them out.
if (waitCount > 0)
{ if (pthread_cond_signal(&cond) != 0)
{ throw int(2);
}
}
}
private:
unsigned int count;
unsigned int waitCount;
pthread_mutex_t mutex;
pthread_cond_t cond;
};

- 257,169
- 86
- 333
- 562
-
@Martin thank you, what I'm looking for as I said above is a way to block my threads. I'm not familiar with pthreads, but I think your code is using busy waiting, since you have that `while(count==0)`. and you mentioned the use of spinlocks that are internally busy waiting, am I right? If it is otherwise, could you provide an explanation about how you're blocking your threads. – atoMerz May 14 '11 at 15:51
-
@AtoMerZ: It is definitely NOT using busy wait. A condition variable **suspends** a thread that calls wait() until it receives a signal. The while loop is required to make sure that another thread has not stolen the the increment count before the released thread gets the lock. A common mistake by inexperienced programmers is to use an `if` rather than `while`. – Martin York May 14 '11 at 18:29
-
1@AtoMerZ: (I have updated the comments to explain why the while is needed). Note. If you don't know what a `condition variable` is you should definitely not be trying to do this yourself. Use one of the pre-built semaphores. All other threading controls are built from the mutex and the condition variable (these are the most basic building blocks apun which everything else is constructed). – Martin York May 14 '11 at 18:43
-
@Martin Thanks again, comments helped. I also read about condition variables, and now I understand 'em. Although there are still questions in my mind, I think I plenty much found what I was looking for. – atoMerz May 15 '11 at 07:48
-
@Martin According to [this][1] `a spinlock is a 'busywait' one.` as I thought. [1]: http://stackoverflow.com/questions/195853/spinlock-versus-semaphore/195863#195863 – atoMerz May 15 '11 at 07:53
-
@AtoMerZ: Thats what happens when you get an internet full of incompetents updating the web with their half remembered CS lectures (rather than going to their books and reading it again). Anyway it is more commonly now called an interlocked increment (I am not sure who popularised it): But here is the MS reference: http://msdn.microsoft.com/en-us/library/dd78zt0c.aspx – Martin York May 15 '11 at 16:09
-
@Martin: First I'm not sure if this is the right place to continue this conversation, if it isn't please inform me. Now that you mention interlocked I remember it, however they're have limited use compared to locks, and I'm guessing by mentioning them you meant they replaced spinlocks (am I correct)? I did look at the link you provided but, I don't see where it says they're NOT busywait. – atoMerz May 16 '11 at 13:04
In .NET, there exists an implementation within the BCL: System.Threading.Semaphore.
For native code on Windows, have a look at the CreateSemaphore Function. If you are targeting Linux, then you can find a semaphore implementation of the Vienna University of Technology here (which I have already used before and works).

- 12,046
- 7
- 51
- 68
In C++, for the way to block threads I would recommend you to use condition variables rather than semaphores. In C#, monitors might be more appropriate.
Even for a rather simple case of Producer-Consumer problem, a semaphore-based solution is harder to do right: doing semaphore increments & decrements in a wrong order could result in problems. On the contrary, a condition-variable-based solution would not have such issues: condition variables are used with a lock (mutex) and the right order of operations is imposed automatically; so after wakeup, a thread already has the lock acquired.
See also my asnwer to When should I use semaphores? where I give another example of condition variable being in my opinion more appropriate for a problem often solved with semaphores.
And to address another your question, I think higher liability to erroneous use and higher complexity of solutions (comparing to alternatives) are the reason why semaphores are not provided by some threading packages. For TBB, I can say that for sure. Thread support in C++11 (designed after Boost.Thread) does not have it too; see Anthony Williams' answer why.

- 1
- 1

- 12,479
- 2
- 36
- 55