Semaphore: Difference between revisions
(API section (like for mutexes) + Ada implementation) |
No edit summary |
||
Line 13: | Line 13: | ||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
Here is an implementation of a semaphore based on protected objects. The implementation provides operations P (seize) and V (release), these names are usually used with semaphores. |
Here is an implementation of a semaphore based on protected objects. The implementation provides operations P (seize) and V (release), these names are usually used with semaphores. |
||
<ada> |
<lang ada> |
||
protected type Semaphore (K : Positive) is |
protected type Semaphore (K : Positive) is |
||
entry P; |
entry P; |
||
Line 20: | Line 20: | ||
Count : Natural := K; |
Count : Natural := K; |
||
end Mutex; |
end Mutex; |
||
</ |
</lang> |
||
The implementation of: |
The implementation of: |
||
<ada> |
<lang ada> |
||
protected body Semaphore is |
protected body Semaphore is |
||
entry P when Count > 0 is |
entry P when Count > 0 is |
||
Line 33: | Line 33: | ||
end V; |
end V; |
||
end Semaphore; |
end Semaphore; |
||
</ |
</lang> |
||
Use: |
Use: |
||
<ada> |
<lang ada> |
||
declare |
declare |
||
S : Semaphore (5); |
S : Semaphore (5); |
||
Line 51: | Line 51: | ||
S.V; -- Release it |
S.V; -- Release it |
||
end; |
end; |
||
</ |
</lang> |
||
It is also possible to implement semaphore as a monitor task. |
It is also possible to implement semaphore as a monitor task. |
Revision as of 15:51, 3 February 2009
Semaphore is a synchronization object proposed by Edsger Dijkstra. A semaphore is characterized by a natural number k. A task may atomically increase or decrease k. When k reaches 0 the tasks attempting to decrease it are blocked. These are released in an unspecified order when other tasks increase k, one per increment.
The natural number k works like a count of available slots for resources. When you (a task) want to use something (an object, a file, any resource) that can only be used by a limited number of tasks (usually one, but possibly more), you see if there are available slots (check the value of k). If there are slots available (k > 0), you take one (decrement k). When you're done with the resource, you free your slot up (increment k). If there were no slots available when you checked (k = 0), you wait until one becomes available.
A semaphore is considered a low-level synchronization primitive. They are exposed to deadlocking, like in the problem of dining philosophers.
See also mutex, a variant of semaphore.
Sample implementations / APIs
Ada
Here is an implementation of a semaphore based on protected objects. The implementation provides operations P (seize) and V (release), these names are usually used with semaphores. <lang ada> protected type Semaphore (K : Positive) is
entry P; procedure V;
private
Count : Natural := K;
end Mutex; </lang> The implementation of: <lang ada> protected body Semaphore is
entry P when Count > 0 is begin Count := Count - 1; end P; procedure V is begin Count := Count + 1; end V;
end Semaphore; </lang> Use: <lang ada> declare
S : Semaphore (5);
begin
S.P; -- Acquire the semaphore ... S.V; -- Release it ... select S.P; -- Wait no longer than 0.5s or delay 0.5; raise Timed_Out; end select; ... S.V; -- Release it
end; </lang> It is also possible to implement semaphore as a monitor task.