Mutex / Mutual Exclusion / Locking mechanism / Block / Sleep
-
if 1 thread is in CS other cannot enter, Return value: None, Parameters:
None
Mutex internal implementation
A mutex is shared state + rules for deciding which thread may enter a
critical section.
mutex's state is stored in ordinary memory owned by the program (often
in the mutex object). other cores.
Once thread asks for mutex, kernel checks that value and puts the
calling thread on a wait queue and schedules it out. Checking the value
as part of waiting prevents a wake-up from being lost if the mutex was
unlocked just before the thread went to sleep.
In short, the CPU performs the fast atomic lock operation, while the
kernel is typically involved only when a thread must sleep or be woken.
library.
Problems with Mutex
| Problem | Description |
|---|---|
| Priority Inversion |
Lower priority process is executing in Critical section, suddenly
High-Priority process is scheduled, lower-priority process is
preempted & thrown out of CS & higher priority process excecutes in
CS. Also if Higher priority thread/process is Busy Waiting then
lower priority process will never get CPU(ie never scheduled). Can PI happen on user-level threads? No, there is no preemption in user level threads. |
| Easy Deadlock | if order of mutex locking/unlocking is not correct, that can led to easy dead-lock situation. See Dead-lock example. |
| Thread holding mutex paniced | if thread-1 which holding the lock panics, whole process would panic. |
| Mutex and data are seperate Entities |
Thread-1,2 are accessing data using mutex, But thread-3 changed the
data without mutex, this should not Happen. Solutions: 1. Making mutex and data as single entity as done in Rust 2. All times keeping in mind that data should not handled outside mutex guards
|
Creating Mutex
| C++11 | POSIX | Rust |
|---|---|---|
|
|
In Rust, data and mutex are not seperate. ie data can be accessed
inside mutex only. This solves the problem which we is present in CPP
|
Wrappers around mutex
lock_guard, unique_lock
These are classes which owns mutex and provide RAII
| lock_guard (smaller=faster) | unique_lock (heavy wrt lock_guard) | |
|---|---|---|
| What |
We donot need to unlock this mutex, When lock_guard object goes out of scope, mutex is automatically unlocked |
Feature rich version of lock_guard |
| Features |
Not copy construtible. Move Assignable. Because operator = is deleted. |
Move Assignable(yes), copy construtible(no) Properties 1. Lock/unlock again after 1st lock. 2. Can be moved to other object 3. deferred locking: Acquire the mutex but donot lock immediately 4. time-constrained attempts at locking: try_lock_for(), try_lock_until() 5. recursive locking |
| Code |
|
Immediate lock
unique_lock <defer_lock> - Donot lock immediately. Most of deadlock problem occur because of immediate mutex locking. - defer_lock delays locking on mutex for some time. defer_lock example(Deadlock)
1 Writer, Multiple Readers
|