110 likes | 289 Views
Classic Synchronization Problems. Classic Synchronization E xamples. Dining philosophers Readers and writers. The Dining Philosophers Problem. Five philosophers sit at a table A fork lies between every pair of philosophers
E N D
Classic Synchronization Examples • Dining philosophers • Readers and writers
The Dining Philosophers Problem • Five philosophers sit at a table • A fork lies between every pair of philosophers • Philosophers (1) think, (2) grab one fork, (3) grab another fork, (4) eat, (5) put down one fork, (6) put the other fork
Dining Philosophers: Try 1 • Assume take_fork and put_fork have locks in them to make them atomic • Is this solution correct? Each philosopher is modeled with a thread #define N 5 Philosopher() { while(TRUE) { Think(); take_fork(i); take_fork((i+1)% N); Eat(); put_fork(i); put_fork((i+1)% N); } }
Dining Philosophers: Try 2 #define N 5 Philosopher() { while(TRUE) { Think(); take_fork(i); take_fork((i+1)% N); Eat(); put_fork(i); put_fork((i+1)% N); } } take_forks(i) put_forks(i)
Take Forks int state[N]; lock mutex; semsem[N] = {0}; // test whether philosopher i // can take both forks // only called with mutex set! test(inti) { if (state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT] != EATING){ state[i] = EATING; // Signal Philosopher i V(sem[i]); } } take_forks(inti) { lock(mutex); state[i] = HUNGRY; test(i); unlock(mutex); P(sem[i]); }
Put Forks int state[N]; lock mutex; semsem[N] = {0}; // test whether philosopher i // can take both forks // only called with mutex set! test(inti) { if (state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT] != EATING){ state[i] = EATING; // Signal Philosopher i V(sem[i]); } } put_forks(inti) { lock(mutex); state[i] = THINKING; test(LEFT); test(RIGHT); unlock(mutex); }
The Readers and Writers Problem • Multiple reader and writer threads want to access some shared data • Multiple readers can read concurrently • Writers must synchronize with readers and other writers • Synchronization requirements • Only one writer can write the shared data at a time • When a writer is writing, no readers must access the data • Goals • Maximize concurrency • Prevent starvation
Readers/Writers - Basics Mutex lock = UNLOCKED; Semaphore data = 1; intrc = 0; Reader () { rc= rc + 1; // Read shared data rc= rc – 1; // non-critical section } Writer () { // non-critical section // Write shared data }
Readers/Writers - Mutex Mutex lock = UNLOCKED; Semaphore data = 1; intrc = 0; Reader () { lock(lock); rc= rc + 1; unlock(lock); // Read shared data lock(lock); rc= rc – 1; unlock(lock); // non-critical section } Writer () { // non-critical section // Write shared data }
Readers/Writers – Synchronization • Any problems with this solution? Mutex lock = UNLOCKED; Semaphore data = 1; intrc = 0; Reader () { lock(lock); if (rc == 0) P(data); rc= rc + 1; unlock(lock); // Read shared data lock(lock); rc= rc – 1; if (rc == 0) V(data); unlock(lock); // non-critical section } Writer () { // non-critical section P(data); // Write shared data V(data); }