220 likes | 429 Views
Dining Philosophers (1). Philosophers eat/think Eating needs 2 forks Pick one fork at a time How to prevent deadlock . Dining Philosophers. A non solution to the dining philosophers problem. semaphore Forks[N] = {1,1,1,1,1} ; void take_fork(int i) { wait (Forks[i]) ; }
E N D
Dining Philosophers (1) • Philosophers eat/think • Eating needs 2 forks • Pick one fork at a time • How to prevent deadlock
Dining Philosophers A nonsolution to the dining philosophers problem
semaphore Forks[N] = {1,1,1,1,1} ; void take_fork(int i) { wait (Forks[i]) ; } void put_fork(int i) { signal(Forks[i]) ; } Problems?
Approach 2: Semaphore Forks[N] = {1,1,1,1,1} ; Semaphore mutex = 1 ; while (1) { think(); wait(mutex) ; take_fork(i) ; take_fork((i+1) % N) ; eat() ; put_fork(i) ; put_fork((i+1) % N) ; signal(mutex) ; } Will this work?
Dining Philosophers Solution to dining philosophers problem (part 1)
Dining Philosophers Solution to dining philosophers problem (part 2)
0 0 0 0 0 State Array S Array T T T T T Mutex = 1 NULL Mutex.queue P0: take_forks(0) down(mutex) ; test(0) ;
1 0 0 0 0 State Array S Array E T T T T Mutex = 0 NULL 2 1 1 1 1 Mutex.queue P0: take_forks(0) down(mutex) ; test(0) ;
State Array S Array E T T T T Mutex = 0 NULL 1 0 0 0 0 Mutex.queue P0: take_forks(0) down(mutex) ; test(0) ; up(mutex) ; down(S[0]) ;
0 0 0 0 0 State Array S Array E T T T T Mutex = 1 NULL Mutex.queue P0: take_forks(0) down(mutex) ; test(0) ; up(mutex) ; down(S[0]) ; // falls through to //critical section Preempted
0 0 0 0 0 State Array S Array E T T T T Mutex = 1 NULL Mutex.queue P0: take_forks(0) down(mutex) ; test(0) ; up(mutex) ; down(S[0]) ; // falls through to //critical section Preempted P2: take_forks(2) ; down(mutex) ; test(2) ;
0 0 1 0 0 State Array S Array E T E T T Mutex = 0 NULL 1 1 2 1 1 Mutex.queue P0: take_forks(0) down(mutex) ; test(0) ; down(S[0]) ; Preempted P2: take_forks(2) ; down(mutex) ; test(2) ;
0 0 0 0 0 State Array S Array E T E T T Mutex = 1 NULL 1 1 2 1 1 Mutex.queue P0: take_forks(0) down(mutex) ; test(0) ; down(S[0]) ; Preempted P2: take_forks(2) ; down(mutex) ; test(2) ; up(mutex) ; down(S[2]) ; //Falls through to critical section
0 0 0 0 0 State Array S Array E T E T T Mutex = 1 NULL 1 1 1 1 1 Mutex.queue P2: take_forks(2) ; down(mutex) ; test(2) ; up(mutex) ; down(S[2]) ; eat() !!! P0: take_forks(0) down(mutex) ; test(0) ; down(S[0]) ; Preempted P3: take_forks(3) ; down(mutex) ; test(3) ; up(mutex) ; down(S[3]) ;
0 0 0 -1 0 State Array S Array E T E H T Mutex = 1 NULL 1 1 1 0 1 Mutex.queue S[3].queue P2: take_forks(2) ; down(mutex) ; test(2) ; up(mutex) ; down(S[2]) ; eat() !!! P0: take_forks(0) down(mutex) ; test(0) ; down(S[0]) ; P3: take_forks(3) ; down(mutex) ; test(3) ; up(mutex) ; down(S[3]) ; P3
0 0 0 -1 0 State Array S Array E T E H T Mutex = 1 NULL 1 1 1 0 1 Mutex.queue S[3].queue P2: take_forks(2) ; down(mutex) ; test(2) ; up(mutex) ; down(S[2]) ; eat() !!! P0: take_forks(0) down(mutex) ; test(0) ; down(S[0]) ; P3: take_forks(3) ; down(mutex) ; test(3) ; up(mutex) ; down(S[3]) ; P3 P2: put_forks(2) ; down(mutex) ; State[2] = Thinking ; test(1) ;
0 0 0 -1 0 State Array S Array E T T H T Mutex = 0 NULL 1 1 1 0 1 Mutex.queue S[3].queue P2: take_forks(2) ; down(mutex) ; test(2) ; up(mutex) ; down(S[2]) ; eat() !!! P0: take_forks(0) down(mutex) ; test(0) ; down(S[0]) ; P3: take_forks(3) ; down(mutex) ; test(3) ; up(mutex) ; down(S[3]) ; P3 P2: put_forks(2) ; down(mutex) ; State[2] = Thinking ; test(1) ;
0 0 0 -1 0 State Array S Array E T T H T Mutex = 0 NULL 1 1 1 0 1 Mutex.queue S[3].queue P2: take_forks(2) ; down(mutex) ; test(2) ; up(mutex) ; down(S[2]) ; eat() !!! P0: take_forks(0) down(mutex) ; test(0) ; down(S[0]) ; P3: take_forks(3) ; down(mutex) ; test(3) ; up(mutex) ; down(S[3]) ; P3 P2: put_forks(2) ; down(mutex) ; State[2] = Thinking ; test(1) ; test(3) ;
0 0 0 0 0 Ready Queue P3 State Array S Array E T T E T Mutex = 0 NULL 1 1 1 0 1 Mutex.queue P2: take_forks(2) ; down(mutex) ; test(2) ; up(mutex) ; down(S[2]) ; eat() !!! P0: take_forks(0) down(mutex) ; test(0) ; down(S[0]) ; P3: take_forks(3) ; down(mutex) ; test(3) ; up(mutex) ; down(S[3]) ; P2: put_forks(2) ; down(mutex) ; State[2] = Thinking ; test(1) ; test(3) ; //performs a signal on S[3]
0 0 0 0 0 Ready Queue P3 State Array S Array E T T E T Mutex = 1 NULL 1 1 1 0 1 Mutex.queue P2: take_forks(2) ; down(mutex) ; test(2) ; up(mutex) ; down(S[2]) ; eat() !!! P0: take_forks(0) down(mutex) ; test(0) ; down(S[0]) ; P3: take_forks(3) ; down(mutex) ; test(3) ; up(mutex) ; down(S[3]) ; P2: put_forks(2) ; down(mutex) ; State[2] = Thinking ; test(1) ; test(3) ; //performs a signal on S[3] up(mutex) ;