4

Reading various posts on SO on differences between the two (mutex and semaphore) I have come to the following conclusion please correct me if I am wrong.This is mostly related to windows. I understand that critical sections are sections in a code that need to be protected (i.e) cannot be accessed by multiple threads at the same time. Now in order to protect those critical sections Mutexes are used. These mutexes can be either algorithms or data structures. Now mutexes can generally be in two flavours (intra process and inter process) . For intra process in which no calls to the kernel for locking are made we could use Boost Thread synchronization primitives such as lock_guard , unique_lock , shared_lock (single writer/multiple readers) and for inter-process we could use Boost Interprocess semaphore.Now these inter-process mutexes are basically called semaphore. The reason I concluded that was because of this post which states

Semaphore is signaling mechanism (“I am done, you can carry on” kind of signal). For example, if you are listening songs (assume it as one task) on your mobile and at the same time your friend called you, an interrupt will be triggered upon which an interrupt service routine (ISR) will signal the call processing task to wakeup.

Now Boost interprocess states

.. Boost.Interprocess implements similar mechanisms to synchronize threads from different processes.

Please let me know if my understanding of semaphore is in the correct direction.

Now another definition of semaphore which I dont understand comes from here the selected answer states

A semaphore does the same as a mutex but allows x number of threads to enter.

Which correctly describes what a semaphore does ? Does it allow interprocess resource protection or does it allow a specific number of threads to access a resource ? If it does the second one wouldn't it corrupt the resource since multiple threads are accessing it.

Community
  • 1
  • 1
MistyD
  • 16,373
  • 40
  • 138
  • 240
  • in windows a semaphore is an Event see [CreateEvent](http://msdn.microsoft.com/en-us/library/windows/desktop/ms682396%28v=vs.85%29.aspx) – AndersK Nov 25 '14 at 06:48
  • A good explanation can be found here: http://koti.mbnet.fi/niclasw/MutexSemaphore.html The bottom line: A mutex is a sempahore with value 1. Basically it doesn't matter wether a resource is accessed by multiple threads or multiple processes. There are differences when accessing memory, but that is another issue. – Devolus Nov 25 '14 at 06:53

2 Answers2

5

A semaphore is a synchronization mechanism build around an integer value. Locking a semaphore (usually called "waiting on semaphore") decreases the value unless it's 0. In that case the thread is stopped until the semaphore value is greater than 0, so it can be properly decreased. Unlocking the semaphore (usually called "posting" or "signalling") increases the value by 1, unconditionally.

Usually when creating a semaphore you need to assign it a starting value. If you set a value bigger than 1, you can have multiple threads enter code "protected" by a semaphore.

Now, a mutex is a binary synchronization primitive. Conceptually it can be compared to a semaphore with an initial value of 1. Only a single thread can enter code protected by a mutex.

I don't know the Windows world, but on Unix semaphore is a OS construct and it can be used to synchronize multiple processes. Pthread mutexes are usually used for coordinating threads within a single process, but there are tricks that allow using mutexes for inter-process synchronization (shared memory block and special ways to create a mutex).

Tomo
  • 3,431
  • 5
  • 25
  • 28
  • Thanks for the answer you said "If you set a value bigger than 1, you can have multiple threads enter code "protected" by a semaphore." I came across [this][1] post which provides a sample code of a semaphore. Are you saying that when a protected resource is accessed the count is decremented ? [1]:http://stackoverflow.com/questions/3928853/how-can-i-achieve-something-similar-to-a-semaphore-using-boost-in-c - Who calls lock ? who calls signal ? – MistyD Nov 25 '14 at 07:59
  • Yes. `wait` has a `--count_` and `condition_.wait()` when the count is 0. `signal()` has an unconditional `++count_` and `condition_.notify_one()` to wake up any thread waiting on the conditional variable. – Tomo Nov 25 '14 at 08:07
  • So are you saying that the code that needs to be protected should be in this semaphore class ? Could you give a rough code example on how this class can be used with 3 threads? – MistyD Nov 25 '14 at 08:12
  • No, the protected code is outside the semaphore. Comments don't allow for entering nicely formatted code. Basically, when you want up to three threads to acces a critical section, you create semaphore with initial value of 3 (`semaphore s(3);`), then you have your code block surrounded by `wait` and `signal`: `s.wait(); /* protected code */; s.signal()`. – Tomo Nov 25 '14 at 08:19
  • Ok that definitely explains the code!. One last thing so if three threads are accessing a protected resource at the same time using a semaphore that does not secure the protected resource from race conditions does it ? Since the three threads might be attempting to alter the resource simultaneously or is that not the responsibility of a semaphore ? – MistyD Nov 25 '14 at 08:26
  • If you need to protect against race consitions, definitely use a mutex. – Tomo Nov 25 '14 at 08:30
  • So you are basically saying that all a semaphore does is that it allows a specifice no of threads to access a resource and its job does not include protecting resources its encapsulating from race conditions. – MistyD Nov 25 '14 at 08:32
  • 1
    You can protect against race conditions with a semaphore with the value of 1. However, there are other considerations, like performance or code readability, that make mutexes better for that job. – Tomo Nov 25 '14 at 08:35
  • @Tomo, refering "performance or code readability, that make mutexes better for that job", do you have some "performance metrics" on for inter-process ? I googled without success. Thks – Jean Davy Jul 27 '15 at 09:06
  • @JeanDavy I made some benchmarking at my previous job. However, the results were confidential and I could not publish any of it. And I left all the data behind when I changed jobs. However, the performance difference shouldn't bother you until you need to fight for nanoseconds in a tight loop (I had to). – Tomo Aug 10 '15 at 10:26
  • @Tomo Yes, I was seeking for order of magnitude. And found it, it was because of the SEM_UNDO semaphore flag. What is cool is that the Windows counterpart is WAIT_ABANDONED and there is no such penalty using it (even with some code to mimic SEM_UNDO). – Jean Davy Aug 10 '15 at 16:56
0

Mutex are used in cases where there is a single object instance(or as OP mentioned critical code section access) that needs to be synchronised. Example: Single producer-consumer accessing a queue/memory block. If the producer currently has mutex locked. The consumer will locked out(blocked) from using it until the producer releases it.

Semaphore is used in cases where there are multiple instances of shared resources. So when a new resource is added we do sem_post and when a resource is taken or used sem_wait(decrement) . When the count goes below 0 that shm_wait would be blocked. This is an example in system V.

Coming back the queue access example above for consumer-producer example, there might be 4KB available and it possible for the sake of argument here to divide access atomically to 1KB, lets say. So semaphore can be incremented to 4 when all 4KB is available and to 0 when none are available.

shazzing
  • 431
  • 4
  • 4