Download presentation
Presentation is loading. Please wait.
Published byMichael Page Modified over 9 years ago
2
Cosc 4740 Chapter 6, Part 2 Process Synchronization
3
Busy loop/waiting problem Wastes CPU time If scheduler takes into account priority, then low priority process (becomes CPU bound), while other may be high priority –If low priority gets the lock, while the high priority process will have to wait longer while low priority process finishes/release lock.
4
Busy loop fix Can use sleep() and wakeup() sleep() blocks the process –it won’t be scheduled wakeup() moves the sleeping process to the ready list. –If it is blocked for other reasons don’t wake it. –The wakeup() call is issued by another process. The sleeper can not wakeup itself. Can be setup for a timed event, ie sleep for 1 second, but O/S “Wakes” the process after 1 second.
5
Producer/Consumer or Bounded buffer problem 2 processes communication by sharing a fix sized buffer. –(limited way): The producer puts stuff in and the consumer takes stuff out. –Producer buffer consumer It can not just put it in or remove it randomly. The buffer can be full or empty. Must be a balance between producer and consumer.
6
First attempt Buffer: //class An array next: //index variable – next input location // –producer interested in this last: // next output location //– consumer interested in this N: //size-fixed for buffer. Producer() while (true) { produce (item) put_info( buffer[next], item) next = (next+1) mod N } This is a simple minded version. Assumes never full, never empty, no problems Consumer() while (true) { get_item(buffer[last], item) last = (last +1) mod n consume(item) }
7
Problems: what if buffer is full or empty? –If full – don’t put_info –if empty – don’t get_item. One solution is a busy waiting loop while empty or full. OR use sleep() and wakeup()
8
int count = 0 // global –shared between the processes = # items in buffer array producer () while (true) { produce (item) if (count == N) sleep(); enter_item(item) count++ if (count == 1) wakeup(consumer) } Consumer () while (true) { if (count == 0) sleep() remove_item(item) count --; if (count == N-1) wakeup(producer) consume(item) }
9
problems: –Consumer codes running reads count and it is zero. Before it goes to sleep, the process is interrupted. –The producer process starts running puts item in buffer, count = 1 and wakeup consumer. Which would do nothing, since it was interrupted and already on the ready-queue. –Consumer switched onto the CPU and then goes to sleep. –Producer runs until buffer is full and it too goes to sleep.
10
The Fix In 1965 Dykstra invented semaphores to solve these problems.
11
Quick Review tsl instruction () –it’s an atomic instruction –allows programmer to set a lock without interruption problem: busy/waiting wastes CPU solution: sleep & wakeup problem: w/ sleep & wakeup – no count of how many proc are sleeping so could put all to sleep
12
Semaphore Synchronization tool that does not require busy waiting Semaphore S – integer variable –contains non-neg integers (>= 0) –Provides a way to count the number of sleep/wakeups invoked Two standard operations modify S: wait() and signal() –Originally called P() and V()
13
Semaphore as General Synchronization Tool Counting semaphore –integer value can range over an unrestricted domain Binary semaphore –integer value can range only between 0 and 1; can be simpler to implement –Also known as mutex locks Can implement a counting semaphore S as a binary semaphore Provides mutual exclusion Semaphore S; // initialized to 1 wait (S); Critical Section signal (S);
14
Semaphore Implementation Must guarantee that no two processes can execute wait() and signal() on the same semaphore at the same time –Wait() and Signal() are also critical sections for the variables S. –Note that applications may spend lots of time in critical sections and therefore busy waiting is not a good solution.
15
Semaphore Implementation (2) With each semaphore there is an associated waiting queue. Each entry in a waiting queue has two data items: – value (of type integer) – pointer to next record in the list Two operations: –block – place the process invoking the operation on the appropriate waiting queue. –wakeup – remove one of processes in the waiting queue and place it in the ready queue.
16
Semaphore Implementation (3) Implementation of wait: wait (S){ S->value--; if (value < 0) { //add this process to //waiting queue for S block(); } Implementation of signal: Signal (S){ value++; if (value <= 0) { //remove a process P //from the waiting queue //for S wakeup(P); } }
17
Deadlock and Starvation Deadlock – two or more processes are waiting indefinitely for an event that can be caused by only one of the waiting processes Let S and Q be two semaphores initialized to 1 P 0 P 1 wait (S); wait (Q); wait (Q); wait (S);. signal (S); signal (Q); signal (Q); signal (S); Starvation – indefinite blocking. A process may never be removed from the semaphore queue in which it is suspended. Priority Inversion – Scheduling problem when lower-priority process holds a lock needed by higher-priority process –Solved via priority-inheritance protocol
18
Classical Problems Solutions using Semaphores –Bounded-Buffer Problem Producer-Consumer Problem –Dining-Philosophers Problem –Readers and Writers Problem
19
Bounded-Buffer Problem N buffers, each can hold one item Semaphore mutex initialized to the value 1 Semaphore full initialized to the value 0 Semaphore empty initialized to the value N.
20
Bounded Buffer Problem (Cont.) The structure of the producer process while (true) { // produce an item produce(item); wait (empty); //check if buffer is full, if yes, block wait (mutex); //enter CR to add item. // add the item to the buffer signal (mutex); //leave CR system. signal (full); //increment full }
21
Bounded Buffer Problem (2) The structure of the consumer process while (true) { wait (full); //check to see if buffer is “full” //start w/full =0, so it blocks if there is nothing yet. wait (mutex); //Enter CR // remove an item from buffer signal (mutex); //leave CR signal (empty); //increment empty // consume the removed item }
22
Bounded Buffer Problem (3) The producer block should be removed when at least 1 item is removed The consumer must tell the producer by a signal(s) operation. Recall that semaphores keep a count of wait() & signal() calls and are atomic functions.
23
Dining-Philosophers Problem 5 philosophers 5 forks Each philosopher –(1) eat –(2) thinks Catch: If a philosopher wants to each it needs two forks
24
philosopher(i) while(1) { think() pick up 2 forks eat() put down forks } Problem: –To eat, a philosopher needs 2 forks –2 neighbors can not eat at the same time. –can not pick up more than 1 fork at a time. –So 1 philosopher might starve!
25
With No locking. philosopher(i) left = I; right = (I+1) mod 5; while(1) { think() pick_fork[right] =1 pick_fork [left ] =1 eat () put_fork [right]=0 put_fork [ left] =0 }
26
With Semaphores semaphore S[5] = {1,1,1,1,1} // init to 1 while (1) { think(); Wait(S[left]); Wait(S[right]); eat () Signal(s[left]); Signal(s[right]); }
27
Now when a fork is not avail, the philosopher will block. Problem: –If all philosophers pick up left fork 1 st, then no right forks are available. We need to be able to pick up both forks or none, so we need a semaphore to do this: make picking up forks atomic.
28
Philosphers(i) {take_forks(i) { Wait(mutex); while(1) { Wait(S[left]); think(); Wait(S[right]); take_forks(i); Signal(mutex); eat();} put_forks(i); } put_forks(i) { Wait(mutex); Signal(S[left]); Signal(S(right]);So what problems arise? Signal(mutex); }
29
So what problems arise? –If philosophers is blocked on a right or left fork, he will be deadlocked, because no other process can put_forks, since it is in it’s critical section! There are other methods that can fix this problem.
30
Readers/writers problem Two types of processes 1.readers – reads information from the database 2.writers – write to the database And we want concurrent access to the database.
31
problem 1 –2 writers try to modify the db at same time. –constraint: At must 1 writer should access the database at any time problem 2 –a reader is attempting to read an entry while it is in the process of being modified and could read an intermediate value (or wrong value). –Constraint: A writer and reader cannot access the database at the same time.
32
try #1 semaphore db = 1; writer () { P(db); // protect db from other writers and readers modify database V(db); } readers () P(db); read database V(db); } no problem with constraints but it excludes other readers
33
try #2 we want to allow multiple readers, but no readers w/ writers v = 0; db =1; writer()reader() P(db)if (v==1) v = 1;read (database) modify(database) v = 0; V(db)
34
Problem: v is not protected. When you access v, it should be w/in a semaphore Why? Also readers can already be in the database, when the writer enters. Writer is not blocked by readers. P(db) in reader, will also block readers too. We want a P(db) block on writers put on the by the 1 st reader only and removed by last reader!
35
Try #3 semaphore mutex int rc =0; //reader count reader() P(mutex) // Protect rc if (rc ==0) { P(db); } rc ++; V(mutex); read database; P(mutex) rc – if (rc ==0) { V(db); } V(mutex); writer() P(db); modify database V(db);
36
This solution allows multi readers –no writer/reader combo, but writer will starve may never get a chance if readers keep arriving. Writer unblocked only when all readers done. So what is a fair solution? –We need to alternate between writers and readers. –You must maintain a count of # of readers reading and you must maintain a flag when writer arrives. –Can be done with higher level primitives to make it easier.
37
Problems with Semaphores Incorrect use of semaphore operations: – signal (mutex) …. wait (mutex) – wait (mutex) … wait (mutex) – Omitting of wait (mutex) or signal (mutex) (or both) Deadlock and starvation
38
higher level primitives There are two primitives that well look at: Conditional Critical Region (CCR) Monitor
39
Conditional Critical Region Explicitly designates a section of the program as critical. –a mechanism to specify variables to be protected in critical region. –conditions under which a critical section may be entered
40
designated critical section region //always assoc w/ resource variable protection resource resourceR1name: v1, v2, … Vn R2name: v1, v2, …, Vn region R1name when B do S end // B: condition of entry: boolean expression // S: statement list // region statements are scattered through the program. Region statements can be nested, but CAUTION: deadlocks become very likely.
41
Example Unisex bathroom problem –single bathroom –2 processes types: male and female constraints –No male & Female in BR at same time, multi- male ok, multi-female ok.
42
resource bathroom: fc=0, mc=0; //protected variables (male count = mc, etc) //Note male and female solution is the same, expect switch mc and fc male() region bathroom when fc = 0 do mc ++; use bathroom mc --; end
43
Problem –The region statement at any one time is only for only one process to be in the region, so multi- male (multi-female) constraints fails
44
Try #2 males() region bathroom when fc==0 do mc++ end use bathroom region bathroom when true do mc-- end
45
Allows concurrency. Second part, protect, so only one process accessing mc at the same time (mutual exclusion). problem: starvation
46
Dinning Philosophers (again) resource eat: forks[5] ={0,0,0,0,0} philosopher(i) //assume left and right are defined think(); region eat when ((fork[left] ==0)&&(fork[right]==0) do fork[left] =1; fork[right]=1; end eating(); region eat when true do fork[left] =0; fork[right]=0; end
47
Monitors A monitor is a collection of procedures and variables and data structures –Processes can access these variables only by invoking the procedures in the monitor –At most 1 process can be active at any time in the monitor. This provides mutual exclusion –Unlike CCR’s the code is NOT scattered. It is in the monitor condition variables provided: 2 operations defined –wait(c): causes the process to block on C – and the processes leaves the monitor –signal(c): unblocks one of the processes. The unblocked process runs immediately.
48
Monitors Only one process may be active within the monitor at a time monitor monitor-name { // shared variable declarations procedure P1 (…) { …. } … procedure Pn (…) {……} Initialization code ( ….) { … } … }
49
Schematic view of a Monitor
50
Condition Variables condition x, y; Two operations on a condition variable: –x.wait () a process that invokes the operation is suspended. –x.signal () resumes one of processes (if any) that invoked x.wait ()
51
Monitor with Condition Variables
52
Condition Variables Choices If process P invokes x.signal (), with Q in x.wait () state, what should happen next? –If Q is resumed, then P must wait Options include –Signal and wait – P waits until Q leaves monitor or waits for another condition –Signal and continue – Q waits until P leaves the monitor or waits for another condition –Both have pros and cons – language implementer can decide –Monitors implemented in Concurrent Pascal compromise P executing signal immediately leaves the monitor, Q is resumed –Implemented in other languages including Mesa, C#, Java
53
Monitor m_name variable1, … procedure P1( …) statements end procedure P2(…) statements end begin // initialization code for variables end end m_name // invoked by:m_name.P1(…)
54
Unisex (again) Bathroom problem again but cure starvation by alternate the sexes if op. sex is waiting int mc, fc, mcw, fcw –// mcw,fcw male/female count waiting condition fq, mq –// mq/fq male/female queue of processes blocked
55
procedure enter_bathroom_f( ) if (mc == 0 && mcw == 0) fc ++ else fcw ++// waiting female count wait(fq)// blocks females fcw –// not waiting any more fc ++// now female is in the bathroom signal(fq)// signal next female, if none, // signal is lost, but ok.
56
procedure exit_bathroom_m( ) // like reader/writer the last male leaving must // signal to female that he has left. mc -- // male left if (mc == 0 && fcw !=0) // last male out and female waiting // signal wakes up just one process. signal (fq) // no other process can interrupt this since the monitor gives exclusive use // to each procedure as each fq is executed, it runs immediately
57
So 2 queues are waiting to enter monitor If only male signal process executes the signal(fq), then processes gets stuck on the queue and everything starts to block –deadlock, so we need to have female signaled to signal the next female to enter. –Also, since signal is last statement, male does not block it is finished. Each condition has its own queue
58
Solution to Dining Philosophers monitor DP { enum { THINKING; HUNGRY, EATING) state [5] ; condition self [5]; void pickup (int i) { state[i] = HUNGRY; test(i); if (state[i] != EATING) self [i].wait; } void putdown (int i) { state[i] = THINKING; // test left and right neighbors test((i + 4) % 5); test((i + 1) % 5); }
59
Solution to Dining Philosophers (2) void test (int i) { if ( (state[(i + 4) % 5] != EATING) && (state[i] == HUNGRY) && (state[(i + 1) % 5] != EATING) ) { state[i] = EATING ; self[i].signal () ; } initialization_code() { for (int i = 0; i < 5; i++) state[i] = THINKING; }
60
Solution to Dining Philosophers (3) Each philosopher I invokes the operations pickup() and putdown() in the following sequence: Philospher(int i) { while (1) { Think() dp.pickup (i) eat() dp.putdown (i) }
61
Solution to Dinning Philosophers (4) Is Deadlock Possible? Is Starvation possible?
62
Q A &
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.