Mutex: Difference between revisions

Content added Content deleted
(Grammar)
Line 2: Line 2:
[[Category:Encyclopedia]]
[[Category:Encyclopedia]]


'''Mutex''' (''abbreviated'' '''Mut'''ually '''Ex'''clusive access) is a synchronization object, a variant of [[semaphore]] with ''k''=1. Mutex is said to be seized by a [[task]] decreasing ''k''. It is released when the task restores ''k''. Mutexes are typically used to protect a shared resource from concurrent access. A [[task]] seizes the mutex, then accesses the resource, and after that releases the mutex.
A '''mutex''' (''abbreviated'' '''Mut'''ually '''Ex'''clusive access) is a synchronization object, a variant of [[semaphore]] with ''k''=1. A mutex is said to be seized by a [[task]] decreasing ''k''. It is released when the task restores ''k''. Mutexes are typically used to protect a shared resource from concurrent access. A [[task]] seizes (or acquires) the mutex, then accesses the resource, and after that releases the mutex.


Mutex is a low-level synchronization primitive exposed to deadlocking. A deadlock can occur with just two tasks and two mutexes (if each task attempts to acquire both mutexes, but in the opposite order). Entering the deadlock is usually aggravated by a [[race condition]] state, which leads to sporadic hangups, very difficult to track down.
A mutex is a low-level synchronization primitive exposed to deadlocking. A deadlock can occur with just two tasks and two mutexes (if each task attempts to acquire both mutexes, but in the opposite order). Entering the deadlock is usually aggravated by a [[race condition]] state, which leads to sporadic hangups, which are very difficult to track down.


=Variants of mutexes=
=Variants of mutexes=


==Global and local mutexes==
==Global and local mutexes==
Usually [[OS]] provides various implementations of mutexes corresponding to the variants of [[task]]s available in the [[OS]]. For example, system-wide mutexes can be used by [[process]]es. Local mutexes can be used only by [[threads]] etc. This distinction is maintained because, depending on the hardware, seizing a global mutex might be thousand times slower than seizing a local one.
Usually the [[OS]] provides various implementations of mutexes corresponding to the variants of [[task]]s available in the OS. For example, system-wide mutexes can be used by [[process]]es. Local mutexes can be used only by [[threads]] etc. This distinction is maintained because, depending on the hardware, seizing a global mutex might be a thousand times slower than seizing a local one.


==Reentrant mutex==
==Reentrant mutex==
A reentrant mutex can be seized by the same [[task]] multiple times. Each seizing of the mutex is matched by releasing it, in order to allow other task to seize it.
A reentrant mutex can be seized by the same [[task]] multiple times. Each seizing of the mutex is matched by releasing it, in order to allow another task to seize it.


==Read write mutex==
==Read write mutex==
A read write mutex can be seized at two levels for ''read'' and for ''write''. The mutex can be seized for ''read'' by any number of tasks. Only one task may seize it '''write''. Read write mutex are usually used to protect resources which can be accessed in a mutable and immutable ways. Immutable (read) access is granted concurrently for many tasks because they do not change the resource state. Read write mutexes can be reentrant, global or local. Further, promotion operations may be provided, that's when a [[task]] that have seized the mutex for ''write'' releases it keeping seized for ''read''. Note that the reverse operation is potentially deadlocking and requires some additional access policy control.
A read write mutex can be seized at two levels for ''read'' and for ''write''. The mutex can be seized for ''read'' by any number of tasks. Only one task may seize it for '''write''. Read write mutexes are usually used to protect resources which can be accessed in mutable and immutable ways. Immutable (read) access is granted concurrently for many tasks because they do not change the resource state. Read write mutexes can be reentrant, global or local. Further, promotion operations may be provided. That's when a [[task]] that has seized the mutex for ''write'' releases it while keeping seized for ''read''. Note that the reverse operation is potentially deadlocking and requires some additional access policy control.


=Deadlock prevention=
=Deadlock prevention=
Line 23: Line 23:


=={{header|Ada}}==
=={{header|Ada}}==
[[Ada]] provides higher-level concurrency primitives, which are complete in the sense that they also allow implementations of the lower-level ones, like mutex. Here is an implementation of a plain non-reentrant mutex based on protected objects.
[[Ada]] provides higher-level concurrency primitives, which are complete in the sense that they also allow implementations of the lower-level ones, like mutexes. Here is an implementation of a plain non-reentrant mutex based on protected objects.


The mutex interface:
The mutex interface:
<lang ada>
<lang ada>protected type Mutex is
protected type Mutex is
entry Seize;
entry Seize;
procedure Release;
procedure Release;
private
private
Owned : Boolean := False;
Owned : Boolean := False;
end Mutex;
end Mutex;</lang>
</lang>
The implementation of:
The implementation of:
<lang ada>
<lang ada>protected body Mutex is
protected body Mutex is
entry Seize when not Owned is
entry Seize when not Owned is
begin
begin
Line 45: Line 42:
Owned := False;
Owned := False;
end Release;
end Release;
end Mutex;
end Mutex;</lang>
Here the entry Seize has a queue of the [[task]]s waiting for the mutex. The entry's barrier is closed when Owned is true. So any task calling to the entry will be queued. When the barrier is open the first task from the queue executes the entry and Owned becomes true closing the barrier again. The procedure Release simply sets Owned to false. Both Seize and Release are protected actions whose execution causes reevaluation of all barriers, in this case one of Seize.
</lang>
Here the entry Seize has a queue of the [[task]]s waiting for the mutex. The entry's barrier is closed when Owned is true. So any task calling to the entry will be queued. When the barrier is open the first task from the queue executes the entry and Owned becomes false closing the barrier again. The procedure Release simply sets Owned to false. Both Seize and Release are protected actions which execution causes reevaluation of all barriers, in this case one of Seize.


Use:
Use: