What are the differences among mutex, semaphore and read write locks
Asked Answered
B

2

9

Any real-time scenarios explaining on each would be appreciated. Is there any other way to handle synchronization apart from these in pthreads. How do mutex differ from recursive-mutexes(any real-time scenario)?

Barstow answered 3/8, 2013 at 20:52 Comment(6)
"In real time" do you mean for real time applications? (such as games)Demonstration
actually read the boost interprocess docs; they are sometimes the same.Jolynjolynn
@Borgleader, games are not real-time applications. Not hard real-time at least. Make sure not to mistake high performance and real-time. wikipediaAmiraamis
@user2601350, It would be nice if you showed some effort. What have you searched and found already? There are many articles regarding synchronization mechanisms on the internet.Amiraamis
@Amiraamis pendantic argument is useless. I was merely asking for clarification on what type of applications he was referring to.Demonstration
@Amiraamis +1 for the joke. OP didn't specify what real-time meant. I was asking for that, both say OSes and games fall into the large category of "real-time applications". While it probably meant the latter this is SO and people wrongly use terminology all the time.Demonstration
I
9

A mutex can be used to protect a shared resource (a variable, a file, a peripheral device) from modifications that could leave it in an inconsistent state.

A semaphore can be used to manage a finite pool of identical shared resources (one important case of this is an IPC queue). Threads can take a resource from the pool, put one to the pool, or wait until one becomes available. Note you may still have to use a mutex in addition to a semaphore (to protect the pool data structure itself).

A read-write lock can be used to protect a shared resource that can be either read or written to (modified). All reader threads can access it simultaneously. A writer thread needs exclusive access.

A conditional variable can be used, together with a mutex, to signal events.

Wikipedia can be used to read about most of this.

Impermissible answered 3/8, 2013 at 21:13 Comment(2)
according to your explanation, what is the different between a read-write lock and mutex then? I am confused.Brennan
@Brennan read-write lock is much like a mutex, but there are two kinds of accesses, read and write, whereas with a mutex all accesses are the same. A read-write lock doesn't allow a write access simultaneously with any other access, but allows many read accesses simultaneously. A mutex disallows any access simultaneously with any other access.Impermissible
J
2

This is very plainly answered in the boost::interprocess docs

What's A Mutex?

Mutex stands for mutual exclusion and it's the most basic form of synchronization between processes. Mutexes guarantee that only one thread can lock a given mutex. If a code section is surrounded by a mutex locking and unlocking, it's guaranteed that only a thread at a time executes that section of code. When that thread unlocks the mutex, other threads can enter to that code region:

//The mutex has been previously constructed

lock_the_mutex();

//This code will be executed only by one thread //at a time.

unlock_the_mutex(); A mutex can also be recursive or non-recursive:

Recursive mutexes can be locked several times by the same thread. To fully unlock the mutex, the thread has to unlock the mutex the same times it has locked it. Non-recursive mutexes can't be locked several times by the same thread. If a mutex is locked twice by a thread, the result is undefined, it might throw an error or the thread could be blocked forever. boost interprocess docs

and

What's A Semaphore?

A semaphore is a synchronization mechanism between processes based in an internal count that offers two basic operations:

Wait: Tests the value of the semaphore count, and waits if the value is less than or equal than 0. Otherwise, decrements the semaphore count. Post: Increments the semaphore count. If any process is blocked, one of those processes is awoken. If the initial semaphore count is initialized to 1, a Wait operation is equivalent to a mutex locking and Post is equivalent to a mutex unlocking. This type of semaphore is known as a binary semaphore.

Although semaphores can be used like mutexes, they have a unique feature: unlike mutexes, a Post operation need not be executed by the same thread/process that executed the Wait operation. boost::interprocess docs

boost interprocess doesn't explicitly have things called reader-writer locks, however it does implement them using shared_locks, and a upgrade_lock and upgrade_to_unique lock

What's a Sharable and an Upgradable Mutex?

Sharable and upgradable mutex are special mutex types that offers more locking possibilities than a normal mutex. Sometimes, we can distinguish between reading the data and modifying the data. If just some threads need to modify the data, and a plain mutex is used to protect the data from concurrent access, concurrency is pretty limited: two threads that only read the data will be serialized instead of being executed concurrently.

If we allow concurrent access to threads that just read the data but we avoid concurrent access between threads that read and modify or between threads that modify, we can increase performance. This is specially true in applications where data reading is more common than data modification and the synchronized data reading code needs some time to execute. With a sharable mutex we can acquire 2 lock types:

Exclusive lock: Similar to a plain mutex. If a thread acquires an exclusive lock, no other thread can acquire any lock (exclusive or other) until the exclusive lock is released. If any thread other has any lock other than exclusive, a thread trying to acquire an exclusive lock will block. This lock will be acquired by threads that will modify the data. Sharable lock: If a thread acquires a sharable lock, other threads can't acquire the exclusive lock. If any thread has acquired the exclusive lock a thread trying to acquire a sharable lock will block. This locking is executed by threads that just need to read the data. With an upgradable mutex we can acquire previous locks plus a new upgradable lock:

Upgradable lock: Acquiring an upgradable lock is similar to acquiring a privileged sharable lock. If a thread acquires an upgradable lock, other threads can acquire a sharable lock. If any thread has acquired the exclusive or upgradable lock a thread trying to acquire an upgradable lock will block. A thread that has acquired an upgradable lock, is guaranteed to be able to acquire atomically an exclusive lock when other threads that have acquired a sharable lock release it. This is used for a thread that maybe needs to modify the data, but usually just needs to read the data. This thread acquires the upgradable lock and other threads can acquire the sharable lock. If the upgradable thread reads the data and it has to modify it, the thread can be promoted to acquire the exclusive lock: when all sharable threads have released the sharable lock, the upgradable lock is atomically promoted to an exclusive lock. The newly promoted thread can modify the data and it can be sure that no other thread has modified it while doing the transition. Only 1 thread can acquire the upgradable (privileged reader) lock. boost interprocess docs

C++ itself does not yet have reader-writer locks (using shared mutexes) but @Howard Hinnet did try to get them in there, if you look here he also provides the code

C++ does not have semaphores, and mutexes are only in the new C++11 standard as far as a I know, which leads to why most of this was about boost::interprocess

Justifier answered 3/8, 2013 at 21:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.