Synchronisation Examples Last time ProducerConsumer using semaphores Today

  • Slides: 12
Download presentation
Synchronisation Examples Last time: Producer-Consumer using semaphores Today: some more examples Bounded Buffer Readers

Synchronisation Examples Last time: Producer-Consumer using semaphores Today: some more examples Bounded Buffer Readers and Writers Dining Philosophers Sleeping Barber 159. 302 1

What is the bounded buffer problem? This is just another name for the Producer-Consumer

What is the bounded buffer problem? This is just another name for the Producer-Consumer problem with a buffer. The solution uses two semaphores thingsinbuffer – initialised to zero spaceinbuffer – initialised to the buffer size The consumer waits on thingsinbuffer and signals spaceinbuffer after it has consumed. The producer waits on spaceinbuffer and signals thingsinbuffer after it has produced. 159. 302 2

What is the Readers and Writers problem? Imagine a large database. Many processes are

What is the Readers and Writers problem? Imagine a large database. Many processes are accessing the database Some only read (readers) and some read and write (writers). A Race conditions may exist where more than one writer is active or a writer and a reader is active. Any number of processes can read at the same time, but if a writer is writing then no other process must be able to access the data. 159. 302 3

Solution to Readers and Writers Shared data semaphore mutex, norw; int readcount=0; mutex=create(1); norw=create(1);

Solution to Readers and Writers Shared data semaphore mutex, norw; int readcount=0; mutex=create(1); norw=create(1); Writer process wait(norw); . . . writing is performed. . . signal(norw); Reader process wait(mutex); readcount = readcount + 1; if (readcount == 1) // first wait(norw); // one signal(mutex); . . . reading is performed. . . wait(mutex); readcount = readcount - 1; if (readcount == 0) // first signal(norw); // one signal(mutex); 159. 302 4

Readers Writers Example 3 Processes At t=10 p 1 read for 30 ms At

Readers Writers Example 3 Processes At t=10 p 1 read for 30 ms At t=20 p 2 read for 30 ms At t=30 p 3 write for 40 ms At t=70 p 1 read for 10 ms At t=80 p 2 read for 10 ms 159. 302 5

Readers Writers Example mutex 0 1 norw 1 readcount 0 0 -1 1 1

Readers Writers Example mutex 0 1 norw 1 readcount 0 0 -1 1 1 2 1 0 -1 0 1 2 0 P 3 W P 2 P 1 -1 R R 159. 302 6

What is the dining philosophers problem? A Problem posed by Dijkstra in 1965. 5

What is the dining philosophers problem? A Problem posed by Dijkstra in 1965. 5 people (philosophers) around a table each need 2 forks to eat. The philosophers alternately eat and think. 159. 302 7

A Possible solution void philosopher(int no) { while(1) {. . . think. . take_fork(no);

A Possible solution void philosopher(int no) { while(1) {. . . think. . take_fork(no); /* get the left fork */ take_fork((no+1) % N); /* get the right fork */. . eat. . . put_fork(no); /* put left fork down */ put_fork((no+1) % N); /* put down right fork */ } } "take_fork" waits until the specified fork is available and then grabs it. Unfortunately this solution will not work. . . what happens if all the philosophers grab their left fork at the same time. 159. 302 8

A Better Solution Shared data int p[N]; /* status of the philosophers */ semaphore

A Better Solution Shared data int p[N]; /* status of the philosophers */ semaphore s[N]=0; /* semaphore for each philosopher */ semaphore mutex=1; /* semaphore for mutual exclusion */ Code #define LEFT(n) (n+N-1)%N /* Macros to give left */ #define RIGHT(n) (n+1)%N /* and right around the table */ void philosopher(int no) { while(1) {. . . think. . take_forks(no); /* get the forks */. . eat. . . put_forks(no); /* put forks down */ } return NULL; } 159. 302 9

A Better Solution void test(int no) { /* can philosopher 'no' eat */ if

A Better Solution void test(int no) { /* can philosopher 'no' eat */ if ((p[no] == HUNGRY) && (p[LEFT(no)] != EATING) && (p[RIGHT(no)] != EATING) ) { p[no]=EATING; signal(s[no]); /* if so then eat */ } } void take_forks(int no) { /* get both forks */ wait(mutex); /* only one at a time here please */ p[no]=HUNGRY; /* I'm Hungry */ test(no); /* can I eat? */ signal(mutex); wait(s[no]); /* wait until I can */ } void put_forks(int no) { /* put the forks down */ wait(mutex); /* only one at a time here */ p[no]=THINKING; /* let me think */ test(LEFT(no)); /* see if my neighbours can now eat */ test(RIGHT(no)); signal(mutex); } 159. 302 10

Philosopher Practice Think for a while Wait until mutex available and grab it. Look

Philosopher Practice Think for a while Wait until mutex available and grab it. Look at people to your left and right If either of them is eating put down mutex and go to sleep otherwise put down mutex Eat for a while Wait until mutex available and grab it, meanwhile keep eating. Stop eating Look at person on your left If they are asleep wake them up if the person to their left is not eating. Look at person on your right If they are asleep wake them up if the person to their right is not eating. Repeat forever. 159. 302 11

Fin 159. 302 12

Fin 159. 302 12