Suggested Exercise 4 Questions and Short Answers Question

  • Slides: 24
Download presentation
Suggested Exercise 4 Questions and Short Answers

Suggested Exercise 4 Questions and Short Answers

Question #1 • What are the differences between semaphores and monitors?

Question #1 • What are the differences between semaphores and monitors?

Question #1 (Answers found in Session 10) • Sempahores increment and decrement – P()

Question #1 (Answers found in Session 10) • Sempahores increment and decrement – P() and V() – Never go below zero • Monitors only work inside of a lock – Uses signal, broadcast, and wait

Question #1 (Answers found in Session 10) • Condition variables have no history, but

Question #1 (Answers found in Session 10) • Condition variables have no history, but semaphores have – Signal() with an empty queue does nothing • A subsequent Wait() will wait – V() increments semaphore • A subsequent P() will not wait

Question #2: Helicopter Problem • A helicopter ride has five seats, and it always

Question #2: Helicopter Problem • A helicopter ride has five seats, and it always carries a full load. • Use lock(s) and condition variable(s) to write a procedure Person. Arrives(), which is called whenever a person (thread) arrives. • Once the load is full, one person (thread) should call Up. And. Away(), and five threads should return from Person. Arrives(). – There should be no undue waiting: the helicopter should depart as soon as it has a full load.

Helicopter Problem int queue = 0; condition ok. To. Go = NULL; Lock lock

Helicopter Problem int queue = 0; condition ok. To. Go = NULL; Lock lock = FREE; Person. Arrives() { lock. Acquire(); ++queue; if (queue < 4) { ok. To. Go. wait(&lock); } else { Go. Go(); queue = 0; ok. To. Go. Signal(&lock); } lock. Release(); }

Helicopter Problem int queue = 0; condition ok. To. Go = NULL; Lock lock

Helicopter Problem int queue = 0; condition ok. To. Go = NULL; Lock lock = FREE; Person. Arrives() { lock. Acquire(); ++queue; if (queue < 5) { ok. To. Go. wait(&lock); } else { Up. And. Away(); = 0; ok. To. Go. Signal(&lock); } lock. Release(); }

Helicopter Problem int queue = 0; condition ok. To. Go = NULL; Lock lock

Helicopter Problem int queue = 0; condition ok. To. Go = NULL; Lock lock = FREE; Person. Arrives() { lock. Acquire(); ++queue; if (queue < 5) { ok. To. Go. wait(&lock); } else { Up. And. Away(); ok. To. Go. Signal(&lock); queue = 0; } lock. Release(); }

Proving Correctness • Mutual exclusion – All shared variables are locked • e. g.

Proving Correctness • Mutual exclusion – All shared variables are locked • e. g. , queue – Signal() and Wait() are invoked between lock. Acquire() and lock. Release()

Proving Correctness • Liveness – Maximum of 4 threads in ok. To. Go. wait()

Proving Correctness • Liveness – Maximum of 4 threads in ok. To. Go. wait() – Every 5 th thread wakes up exactly four threads already waiting in ok. To. Go. wait() – Additional threads wait at lock. Acquire() – As long as we have 5 n threads, every thread will make progress

Proving Correctness • Fairness – As long as we have FIFO queues at lock.

Proving Correctness • Fairness – As long as we have FIFO queues at lock. Acquire() – The queuing policy at ok. To. Go. wait() does not matter, since all four waiting threads will be awakened – As long as we have 5 n threads – Every thread will get its chance

Common Pitfall int queue = 0; condition ok. To. Go = NULL; Lock lock

Common Pitfall int queue = 0; condition ok. To. Go = NULL; Lock lock = FREE; Person. Arrives() { lock. Acquire(); ++queue; if (queue < 5) { ok. To. Go. wait(&lock); } else { Up. And. Away(); ok. To. Go. Signal(&lock); queue = 0; lock. Release(); } } Wait() requires lock on return No lock. Release()

Question #3 Deadlock Prevention Techniques How is this version broken? // chopstick[5] = {1,

Question #3 Deadlock Prevention Techniques How is this version broken? // chopstick[5] = {1, 1, 1}, s = 1; person(int j) { while (TRUE) { P(s); P(chopstick[j]); P(chopstick[(j + 1) % 5]; V(s); // eat P(s); V(chopstick[(j + 1) % 5]; V(chopstick[j]); V(s); } }

Deadlock Prevention Techniques How is this version broken? 1 // chopstick[5] = {1, 1

Deadlock Prevention Techniques How is this version broken? 1 // chopstick[5] = {1, 1 0, 1, 1}, s = 1 0 1; person(int j) { while (TRUE) { P(s); P(chopstick[j]); P(chopstick[(j + 1) % 5]; V(s); // eat P(s); V(chopstick[(j + 1) % 5]; V(chopstick[j]); V(s); } }

Deadlock Prevention Techniques How is this version broken? 1 3 // chopstick[5] = {1,

Deadlock Prevention Techniques How is this version broken? 1 3 // chopstick[5] = {1, 0, 0, 1 0}, s = 1 0 1; person(int j) { while (TRUE) { P(s); P(chopstick[j]); P(chopstick[(j + 1) % 5]; V(s); // eat P(s); V(chopstick[(j + 1) % 5]; V(chopstick[j]); V(s); } }

Deadlock Prevention Techniques How is this version broken? 1 3 // chopstick[5] = {1,

Deadlock Prevention Techniques How is this version broken? 1 3 // chopstick[5] = {1, 0, 0}, s = 1 0; person(int j) { while (TRUE) { 2 P(s); P(chopstick[j]); // deadlock P(chopstick[(j + 1) % 5]; V(s); // eat P(s); V(chopstick[(j + 1) % 5]; V(chopstick[j]); V(s); } }

Deadlock Prevention Techniques How is this version broken? 1 3 // chopstick[5] = {1,

Deadlock Prevention Techniques How is this version broken? 1 3 // chopstick[5] = {1, 0, 0}, s = 0; person(int j) { while (TRUE) { 2 P(s); P(chopstick[j]); P(chopstick[(j + 1) % 5]; V(s); // eat P(s); // deadlock V(chopstick[(j + 1) % 5]; V(chopstick[j]); V(s); } }

Fixing Dining Philosophers semaphore chopstick[5] = {1, 1, 1}, s = 1; philosopher (int

Fixing Dining Philosophers semaphore chopstick[5] = {1, 1, 1}, s = 1; philosopher (int j) { while (TRUE) { P(s); P(chopstick[j]); P(chopstick[(j + 1) % 5]; V(s); // eat P(s); V(chopstick[(j + 1) % 5]; V(chopstick[j]); V(s); } } This solution works, but it is very inefficient. (Only one thread/philosopher is allowed to eat at a time. ) We can do better!

Fixing Dining Philosophers Allocate all resources at the beginning (if you need 2 chopsticks,

Fixing Dining Philosophers Allocate all resources at the beginning (if you need 2 chopsticks, grab both at the same time) – slide 29, session 11 int counter[5] = {1, 1, 1}; semaphore chopstick[5] = {1, 1, 1}, s = 1; person(int j) { while (TRUE) { P(s); // if both counters j and (j + 1) % 5 > 0, decrement counters // and grab chopstick[j] and chopstick[(j + 1) % 5] V(s); // if holding both chopsticks, eat P(s); // release chopsticks and increment counters as needed V(s); } }

Fixing Dining Philosophers Make everyone use the same ordering in accessing resource (All threads

Fixing Dining Philosophers Make everyone use the same ordering in accessing resource (All threads must call P(x) before P(y) – slide 33, session 11 semaphore chopstick[5] = {1, 1, 1}; person(int j) { while (TRUE) { P(chopstick[min(j, (j + 1) % 5)]); P(chopstick[max(j, (j + 1) % 5)]); // eat V(chopstick[max(j, (j + 1) % 5)]); V(chopstick[min(j, (j + 1) % 5)]); } }

Question #4 Suppose we are using the banker's algorithm with 512 MB of RAM

Question #4 Suppose we are using the banker's algorithm with 512 MB of RAM to share among the processes. Determine if the system is in a safe state or an unsafe state and explain why. Process Allocated Still needed P 1 100 MB 30 MB P 2 230 MB 10 MB P 3 120 MB 400 MB

Question #4 Suppose we are using the banker's algorithm with 512 MB of RAM

Question #4 Suppose we are using the banker's algorithm with 512 MB of RAM to share among the processes. Determine if the system is in a safe state or an unsafe state and explain why. Process Allocated Still needed P 1 100 MB 30 MB P 2 230 MB 10 MB P 3 120 MB 400 MB Suppose P 1 goes first. Allocate the 30 MB of RAM, free RAM=62 -30=32. Then give back 130 MB to the system. Free RAM = 32+130=162 MB

Question #4 Suppose we are using the banker's algorithm with 512 MB of RAM

Question #4 Suppose we are using the banker's algorithm with 512 MB of RAM to share among the processes. Determine if the system is in a safe state or an unsafe state and explain why. Process Allocated Still needed P 2 230 MB 10 MB P 3 120 MB 400 MB 162 MB Suppose P 2 goes second. Allocate the 10 MB of RAM, free RAM=162 -10=152. Then give back 240 MB to the system. Free RAM = 152+240=392 MB

Question #4 Suppose we are using the banker's algorithm with 512 MB of RAM

Question #4 Suppose we are using the banker's algorithm with 512 MB of RAM to share among the processes. Determine if the system is in a safe state or an unsafe state and explain why. Process Allocated Still needed P 3 120 MB 400 MB 162 MB 392 MB Uh oh! The system is not in a safe state, because we don’t have 400 MB to give to P 3 for it to continue. Bummer.