Download presentation
1
Chapter 6 Semaphores
2
Semaphores Major advance incorporated into many modern operating systems (Unix, OS/2) A semaphore is a non-negative integer that has two indivisible, valid operations
3
Semaphore Operations Wait(s) (Dijkstra – P(s) – Proberen (to test)
If s > 0 then s:= s - 1 else block this process Signal(s) (Dijkstra – V(s) – Verhogen (to increment) If there is a blocked process on this semaphore then wake it up else s:= s + 1
4
More on Semaphores The other valid operation is initialisation
Two types of semaphores binary semaphores can only be 0 or 1 counting semaphores can be any non-negative integer Semaphores are an OS service implemented using one of the methods shown already usually by disabling interrupts for a very short time
5
The Critical Section Problem for Two Processes
Note : S ← (1,ø) means semaphore S has a value of 1 and the set of blocked processes is null
6
State Diagram Mutual exclusion : Try to find a state (p2, q2) in which both processes are in their CS. Since there is no such state, mutual exclusion property holds No Deadlock : No states in which both processes are blocked No Starvation : If a process executes its wait statement, the next state is either CS or blocked. When blocked the only way is to a state in which the blocked process continues with a signal statement
7
The Critical Section Problem for N Processes
Mutual exclusion and freedom from deadlock are still hold but there may be starvation
8
Scenario for Starvation (3 Processes)
Processes p and r conspire to starve process q (see lines 3 and 7)
9
Order Of Execution Problems
This mergesort algorithm uses two independent sort processes (may be more) and a merge process to merge the first and second halves when sorting is over The correct synchronization is achived by two binary semaphores as shown above
10
Producer - Consumer with a Single Buffer
Program producerconsumer; Var s: semaphore; Procedure producer; begin repeat produce; wait(s); putinbuffer; signal(s); until false; End; Procedure consumer; Begin getfrombuffer; consume; Begin (* main program *) s:= 1; cobegin producer; consumer coend; End.
11
Producer - Consumer with Infinite Number of Buffers
Program producerconsumer; Var s: semaphore; (* for mutual exclusion on access to buffer *) n: semaphore; (* to control empty and full buffer conditions *) Procedure producer; begin repeat produce; wait(s); putinbuffer; signal(s); signal(n); (* send a full buffer ready signal *) until false; End; Procedure consumer; Begin wait(n); (* wait for a full buffer *) wait(s); getfrombuffer; signal(s); consume; Begin (* main program *) s:= 1; n:= 0; cobegin producer; consumer coend; End.
12
Producer - Consumer with Infinite Number of Buffers (modification 1)
Program producerconsumer; Var s: semaphore; n: semaphore; Procedure producer; begin repeat produce; wait(s); putinbuffer; signal(n); signal(s); until false; End; Procedure consumer; Begin wait(n); wait(s); getfrombuffer; signal(s); consume; until false; Begin (* main program *) s:= 1; n:= 0; cobegin producer; consumer coend; End. signal(s); signal(n); in producer is changed to signal(n); signal(s); Any change in solution? No change since producer can not be blocked in CS but CS is a bit long now.
13
Producer - Consumer with Infinite Number of Buffers (modification 2)
Program producerconsumer; Var s: semaphore; n: semaphore; Procedure producer; begin repeat produce; wait(s); putinbuffer; signal(s); signal(n); until false; End; Procedure consumer; Begin wait(s); wait(n); getfrombuffer; signal(s); consume; Begin (* main program *) s:= 1; n:= 0; cobegin producer; consumer coend; End. wait(n); wait(s); in consumer is changed to wait(s); wait(n); Any change in solution? Suppose consumer enters CS with n = 0. It will be blocked on wait(n). Producer can not also enter CS. So, the system is DEADLOCKED!
14
Producer - Consumer with Finite Number of Buffers
Program producerconsumer; Var s: semaphore; full, empty: semaphore; Procedure producer; begin repeat produce; wait(emtpy); wait(s); putinbuffer; signal(s); signal(full); until false; End; Procedure consumer; Begin wait(full); wait(s); getfrombuffer; signal(s); signal(empty); consume; Begin (* main program *) s:= 1; full:= 0; empty:= 10; (* 10 empty buffers initially *) cobegin producer; consumer coend; End.
15
Dining Philosophers 5 seating places, 5 plates of spagetti and 5 forks
Figure is from Modern OS by Tanenbaum 5 seating places, 5 plates of spagetti and 5 forks A philosophers life cycle Repeat think; eat forever Eating can only be done with 2 forks Devise a ritual (protocol) that will allow the philosophers to eat. The protocol should satisfy mutual exclusion (no two philosophers try to use the same fork simultaneously) , free from deadlock and absense of starvation
16
Dining Philosophers Solution – First Attempt
Program diningphilosophers; Var i : integer; fork : array[0..4] of semaphore; Procedure philosopher (i : integer); Begin repeat think; wait(fork[i]); (* get left fork *) wait(fork[(i+1) mod 5]; (* get right fork *) eat; signal(fork[i]); (* return left fork *) signal(fork[(i+1) mod 5]; (* return right fork *) until false; End; Begin (* main *) for i:= 0 to 4 do fork[i]:= 1; (* initially all forks are available *) cobegin philosopher(0); philosopher(1); philosopher(2); philosopher(3); philosopher(4); coend; End.
17
Comments on First Attempt
Mutual exclusion is implemented by a binary semaphore fork Deadlock is possible if all 5 philosophers take the left forks simultaneously then all would wait for the right fork How to handle the deadlock and ensure liveliness? Let at the most 4 philosophers to sit and eat. Two of them can eat, one holds a fork and the other just sits One philosopher can eat and the other 3 can hold their left forks
18
Correct Solution Program diningphilosophers;
Var fork : array[0..4] of semaphore; i : integer; table : semaphore; (* seating limit *) Procedure philosopher (i : integer); Begin repeat think; wait(table); wait(fork[i]); (* get left fork *) wait(fork[(i+1) mod 5]; (* get right fork *) eat; signal(fork[i]); (* return left fork *) signal(fork[(i+1) mod 5]; (* return right fork *) signal(table); until false; End; Begin (* main *) for i:= 0 to 4 do fork[i]:= 1; table:= 4; cobegin philosopher(0); philosopher(1); philosopher(2); philosopher(3); philosopher(4); coend; End.
19
Barz’s Simulation of General Semaphores
K is the initial value of semaphore Semaphore gate is used to block and unblock processes Variable count holds the value of semaphore simulated Semaphore S is used as a mutex when accessing the count variable
20
Simulated Wait The first process to execute a simulated wait will pass through p1 since gate is initialized to 1, but others will be blocked The first process and each subsequent process (up to a total of k-1) will execute p5 so that other processes will pass through the gate The k’th process will be blocked (count is now 0) at p1
21
Courseware We will use the concurrent Pascal interpreter of Ben-Ari to solve our concurrent programs using semaphores. A new data type “semaphore” is available to declare semaphores. The initial value of a semaphore can be set in the main program section using an assignment (original concurent Pascal) or by an initialsem (BACI, jBACI) statement. Apart from this, you can only use semaphores in “wait” and “signal” primitives. You should not inspect or try to assign a value for a semaphore in the program. The interpreter has a new construct “cobegin ... coend” to start concurrent processes in the main section of your program The concurrent Pascal interpreter has two versions. Unfortunately both versions have slight differences
22
Ben-Ari’s Original Ben-Ari’s original is in the appendix of the book “Concurrent Programming By M. Ben-Ari” I have modified this SW so that it can accomodate more concurrent processes and a “for” loop can be used within the “cobegin..coend” block (which is not compatible with the version described on the next slide). You can find this version (source and executable) in my public directory
23
BACI and jBACI BACI stands for Ben-Ari’s Concurrent Interpreter
BACI url: This software is available for Windows and Unix environments in C and Pascal. The other version jBACI is maintained by Ben-Ari himself jBACI url: I will use jBACI Windows and Pascal versions (You should do the same for this course). To use jBACI you should install and run the Sun java runtime environment which is available at
24
Example 1 - Tunnel A computer system is being used to control the flow of traffic through a road tunnel. For safety reasons, there must never be more than approximately N vehicles in the tunnel at one time. Traffic lights at the entrance control the entry of traffic and vehicle detectors at entrance and exit are used to measure the traffic flow. An entrance process records all vehicles entering the tunnel, and a separate exit process records all vehicles leaving. Each of these processes can, at any time, read its vehicle detector to determine how many vehicles have passed since the last reading was made. A traffic lights process controls the traffic lights at the entrance to the tunnel which is set to red whenever the number of vehicles in the tunnel equals or exceeds N, and green otherwise.
25
Tunnel Program program tunnel; const limit = 5;
Var no_vehicles : integer; {in tunnel} red : boolean; {traffic light} screen : semaphore; {controls screen display screen} i : integer; max : integer; procedure entrance; end; procedure exit; end; procedure lights; end; begin {main} no_vehicles := 0; max:= limit*2; red:= false; initialsem(screen,1); cobegin lights; entrance; exit coend; end.
26
Procedure Entrance procedure entrance; var entry_counter :integer;
begin while true do if not red then begin entry_counter:= random(max); no_vehicles:= no_vehicles + entry_counter; wait(screen); write(' Entry reading .. ',entry_counter); end else begin write(' Light is now RED ... '); end; writeln(' No of vehicles in tunnel .. ',no_vehicles); signal(screen);
27
Procedure Exit procedure exit; var exit_counter :integer; begin
while true do exit_counter:= random(no_vehicles); no_vehicles:= no_vehicles - exit_counter; wait(screen); writeln(' Vehicles passed .. ',exit_counter, ' No of vehicles in tunnel .. ',no_vehicles); signal(screen); end;
28
Procedure Lights procedure lights; begin while true do
if no_vehicles >= limit then red:= true else red:= false; wait(screen); write(' Traffic light is .. '); if red then writeln('RED') else writeln('GREEN'); signal(screen); end;
29
Example 2 – The Bear and The Bees
There are n honeybees and a hungry bear which share a pot of honey. The pot is initially empty; its capacity is H portions of honey. The bear sleeps until the pot is full, then eats all the honey and goes back to sleep. Each bee repeatedly gathers one portion of honey and puts it in the pot; the bee who fills the pot wakes up the bear.
30
Bear and Bees Program Program bear_and_bees; const n = 3; {three bees}
h = 7; {portions for pot} var i : integer; pot : integer; screen : semaphore:=1; potmutex : semaphore:=1; (* access to pot is mutually exclusive *) bear_wakeup : semaphore:=0; (* bear is sleeping *) bee_fill_pot : semaphore:=h; procedure eat; var i : integer; begin for i:= 1 to random(50) do end; procedure gather_honey; var i : integer; begin for i:= 1 to random(15) do end; procedure bee(i:integer); end; procedure bear; end; begin {main} pot:= 0; cobegin bee(1); bee(2); bee(3); bear coend; end.
31
Procedure Bee procedure bee(i:integer); begin repeat
wait(bee_fill_pot); (* wait for a signal to start filling when bear finishes the pot *) wait(screen); writeln('bee : ',i,' is gathering honey '); signal(screen); gather_honey; wait(potmutex); if pot < h then pot:=pot+1; (* update pot *) wait(screen); writeln('bee : ',i,' is filling the pot which has ',pot,' portions now'); signal(screen); if pot = h then begin signal(bear_wakeup); (* wake up bear when pot is full *) wait(screen); writeln('bee : ',i,' is waking the bear up .. pot = ',pot); signal(screen) end; signal(potmutex); (* now other bees can fill the pot *) until false;
32
Procedure Bear procedure bear; var j : integer; begin repeat
wait(screen); writeln('bear is now sleeping'); signal(screen); wait(bear_wakeup); (* bear wakes up *) wait(screen); writeln('bear is now awake and is eating ',pot,' portions'); signal(screen); pot:=0; eat; for j:= 1 to h do signal(bee_fill_pot); (* signal bees *) until false; end;
33
Comments on Solution Time taking actions can be simulated using a loop which executed in a random fashion as in “eat” and “gather_honey” A semaphore should be used for each write statements so that they are in order. The interpreter executes the pseudo code of a process for a number of instructions and the switches the process. If the process is interrupted while writing, the output may mixed with the output of other processes.
34
Example 3 – A Three Way Rendezvous
{ Consider three processes p1, p2, and p3. Implement a 3-way rendezvous to synchronize these processes } program synchronization; const n = 3; var s : array[1..n] of semaphore; {signal to send and wait at the rendezvous point } screen : semaphore; {for the screen} i : integer; procedure p(i :integer); end; begin {main} for i:= 1 to n do initialsem(s[i],0); initialsem(screen,1); cobegin p(1); p(2); p(3) coend; end.
35
Procedure P procedure p(i :integer); var j,k,r :integer; begin
while true do r:= random(100); wait(screen); writeln('Process ',i,' is executing for ',r,' units'); signal(screen); k:=0; for j:= 1 to r do k:= k+ 1; (* let time pass *) wait(screen); writeln('Process ',i,' is waiting for others ..'); signal(screen); for j:= 1 to n do if j <> i then signal(s[j]); (* send arrival messages *) for j:= 1 to n-1 do wait(s[i]); (* wait for reply from each process *) wait(screen); writeln('Process ',i,' has made the rendezvous ..'); signal(screen); end;
36
Comments on Solution When a process p reaches a rendezvous point it sends messages to the other processes to announce the fact that it had arrived. After that, it waits acknowlegements from the other processes before proceeding.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.