Download presentation
Presentation is loading. Please wait.
Published byKarin Blake Modified over 9 years ago
1
CS 149: Operating Systems February 19 Class Meeting Department of Computer Science San Jose State University Spring 2014 Instructor: Ron Mak www.cs.sjsu.edu/~mak
2
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 2 Semaphores A semaphore is a shared variable that holds an integer value and has atomic actions: Testing and modifying a semaphore’s value must all be done without interruption. _ wait(s) { while (s <= 0) block; s--; } signal(s) { s++; }
3
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 3 Semaphores, cont’d A semaphore that can have any integer value is a counting semaphore. Used to ensure processes that depend on each other will execute in the proper sequence: Statement S2 can only execute after statement S1. A binary semaphore only has the values 0 or 1. Also called a mutex, to implement mutual exclusion: S1; signal(s); wait(s); S2; wait(m); // execute critical region signal(m); Informally, just “semaphore” means “counting semaphore”. Just say “mutex” rather than “binary semaphore”.
4
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 4 Readers-Writers Problem Suppose that a file is a shared resource among multiple processes. It is permissible for multiple processes to be reading the file at the same time. But if one process is writing to the file, no other process (reader or writer) can access the file. Can we use semaphores (counting semaphores) and mutexes (binary semaphores) to solve this problem? _
5
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 5 Readers-Writers Problem, cont’d If no processes are currently accessing the file, then either a reader process or a writer process can start to access the file. If a writer process starts to access the file: It must prevent any other reader or writer process from accessing the file until it’s done. If a reader process starts to access the file: It should allow other reader processes to access the file. It should prevent a writer process from accessing the file. _
6
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 6 Readers-Writers Problem, cont’d Use semaphore rw_sem to keep other processes from accessing the file. The writer process must always wait on rw_sem. The first reader process to access the file must wait on rw_sem to force any writer processes to wait. However, subsequent reader processes don’t have to wait, since multiple readers can read the file at the same time. The last reader process to complete its access of the file must signal the semaphore to let in any waiting writer process. Therefore, we must keep a count of how many reader processes are currently accessing the file. If the count > 0, then a writer process can’t access the file.
7
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 7 Readers-Writers Problem, cont’d Writer process: Semaphore rw_sem = 1; // one shared resource (the file) void writer(void) { for (;;) { wait(&rw_sem); // keep out all other processes... // write to the file signal(&rw_sem); // let in a waiting process } } Pseudocode
8
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 8 Readers-Writers Problem, cont’d Reader process: int count = 0; // count of reader processes void reader(void) { for (;;) { count++; if (count == 1) { // the first reader only wait(&rw_sem); // keeps out writers }... // read the file count--; if (count == 0) { // the last reader only signal(&rw_sem); // lets in a waiting writer } } } What is wrong with this code? We have a race condition with shared variable count. Pseudocode
9
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 9 Readers-Writers Problem, cont’d We have a race condition with variable count. Therefore, any reader code that accesses count should be a critical region. Use a mutex to enforce the mutual exclusion. _
10
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 10 Readers-Writers Problem, cont’d Reader processes (corrected): int count = 0; // count of reader processes Mutex mutex = 1; void reader(void) { for (;;) { lock(&mutex); // start critical region count++; if (count == 1) { // first reader only wait(&rw_sem); // keep out writers } unlock(&mutex); // end critical region... // read the file lock(&mutex); // start critical region count--; if (count == 0) { // last reader only signal(&rw_sem); // let in a waiting writer } unlock(&mutex); // end critical region } } Pseudocode
11
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 11 Dining Philosophers Problem Five philosophers are seated at a round table. Each philosopher has a plate of spaghetti. There is a single fork between each plate. A philosopher alternates between thinking and eating. In order to eat spaghetti, a philosopher must obtain both the left and the right fork. How can we enable all the philosophers to eat with the shared forks? Concurrency-control problem: How to allocate limited resources among competing processes. No deadlocks No starvation (in the process sense)
12
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 12 Dining Philosophers Problem, cont’d Lunchtime in SJSU’s Department of Philosophy. Operating Systems: Design and Implementation Tanenbaum & Woodhull (c) 2006 Prentice-Hall, Inc. All rights reserved. 0-13-142938-8
13
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 13 Dining Philosophers Problem, cont’d Why won’t this work? What if each philosopher simultaneously picks up the left fork? Starvation! A possible fix: After failing to get a fork, wait a random amount of time and try again. Is there a solution that doesn’t involve retries? #define N 5 void dine(int id) { int left = id; int right = (id+1)%N; for (;;) { think(); take_fork(left); take_fork(right); eat(); release_fork(left); release_fork(right); } }
14
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 14 Dining Philosophers Problem: A Solution Since the forks are a shared resource, the dining code that accesses forks are a critical region. Therefore, use a mutex to enforce mutual exclusion. Lock the mutex before taking the forks. Unlock the mutex after releasing the forks. Problems? Only one philosopher can eat at a time! _ for (;;) { think(); lock(&mutex); take_fork(left); take_fork(right); eat(); release_fork(left); release_fork(right); unlock(&mutex); }
15
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 15 Dining Philosophers Problem: Another Solution Use an array of semaphores, one per philosopher. A hungry philosopher can block if the needed forks are unavailable. Use a shared array to keep track of each philosopher’s state: THINKING HUNGRY (wants to get forks) EATING Use a mutex to protect the shared state array. Don’t allow a philosopher to enter its EATING state if either of its neighbors are eating.
16
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 16 Dining Philosophers: Another Solution, cont’d Operating Systems: Design and Implementation Tanenbaum & Woodhull (c) 2006 Prentice-Hall, Inc. All rights reserved. 0-13-142938-8
17
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 17 lock(&mutex); unlock(&mutex); wait(&s[i]); When and how is a philosopher ever unblocked? Dining Philosophers: Another Solution, cont’d Operating Systems: Design and Implementation Tanenbaum & Woodhull (c) 2006 Prentice-Hall, Inc. All rights reserved. 0-13-142938-8
18
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 18 lock(&mutex); unlock(&mutex); signal(&s[i]); Dining Philosophers: Another Solution, cont’d Operating Systems: Design and Implementation Tanenbaum & Woodhull (c) 2006 Prentice-Hall, Inc. All rights reserved. 0-13-142938-8
19
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 19 Concurrent Programming Most popular computers today are multicore. Concurrent programming is rapidly becoming a necessary job skill. You will be less successful as a programmer if you only know how to do single-process or single-threaded programming. You should strongly consider taking CS 159 Introduction to Parallel Processing _ WARNING: Soapbox!
20
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 20 Concurrent Programming, cont’d Even though concurrent programming is important, it is hard today for most programmers because there is weak support for it by most programming languages. Object-oriented programming was only an interesting research topic not too long ago. Those eggheads at PARC did object-oriented programming in an obscure language called SmallTalk. Computer scientists realized that it was important. Languages like C++ and Java were invented that had built-in support for object-oriented programming. Today, we teach OO design to beginning programmers. With better language support, we will soon have to teach concurrent programming to beginning programmers.
21
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 21 Monitors Monitors are a new language feature to support concurrent programming. A monitor is an abstract data type (ADT). It has a set of operations that support mutual exclusion and process sequencing. But the programmer who uses the monitor doesn’t need to know (or care) how these operations are implemented. _
22
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 22 Monitors, cont’d A monitor (like any other class) has one or more methods. You instantiate a monitor to get a monitor object. Only one process at a time can be executing any one of a monitor object’s methods. Therefore, each monitor method is by default a critical region that supports mutual exclusion. To support process sequencing, a monitor has condition variables. Call wait() and signal() on a condition variable. Condition variables are similar to semaphores.
23
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 23 Java Monitors The Java programming language supports the concept of monitors. Define a class, as usual. You can even name the class Monitor. Not necessary, of course. Create objects of the class as usual. Mark methods of the class as synchronized. At run time, only one process or thread can be executing any synchronized method of the monitor object. Therefore, each synchronized method is a critical region. No explicit mutexes are necessary. _
24
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 24 Java Monitors, cont’d Each Java object has one built-in condition variable. Use the Thread class methods wait() and notifyAll(). notifyAll() is equivalent to signal(). _
25
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 25 Dining Philosophers: Java Solution public class DiningPhilosophers { static Philosopher philosophers[]; // philosopher threads static ForkMonitor monitor; public static void main(String args[]) throws Exception {... philosophers = new Philosopher[philosopherCount]; monitor = new ForkMonitor(philosophers); for (int i = 0; i < philosopherCount; i++) { philosophers[i] = new Philosopher(i, monitor); }... for (int i = 0; i < philosopherCount; i++) { philosophers[i].start(); }... } } philosopherCount is a command-line argument. Create the philosopher theads. Start the philosopher theads.
26
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 26 Dining Philosophers: Java Solution, cont’d public class DiningPhilosophers {... public static void main(String args[]) throws Exception {... try { Thread.sleep(1000*seconds); } catch(InterruptedException ex) {} for (int i = 0; i < philosopherCount; i++) { philosophers[i].timesUp(); philosophers[i].join(); } for (int i = 0; i < philosopherCount; i++) { System.out.printf("%-12d", philosophers[i].eaten()); } System.out.println(); } } seconds is a command-line argument. Sleep while the philosopher theads are running. Kill the philosopher theads. Print how many times each philosopher ate.
27
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 27 Dining Philosophers: Java Solution, cont’d public class Philosopher extends Thread { private int id; private State state; private int timesEaten; private boolean eatThink; private ForkMonitor monitor; private Random generator = new Random(); public enum State {THINKING, WAIT_LEFT, WAIT_RIGHT, EATING}; public Philosopher(int id, ForkMonitor monitor) { this.id = id; this.state = State.THINKING; this.timesEaten = 0; this.eatThink = true; this.monitor = monitor; }... } States that a philosopher can be in.
28
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 28 Dining Philosophers: Java Solution, cont’d public class Philosopher extends Thread {... public int id() { return this.id; } public int eaten() { return this.timesEaten; } public State state() { return this.state; } public void changeState(State state) { this.state = state; DiningPhilosophers.print(); } public void ateAgain() { ++timesEaten; } public void timesUp() { eatThink = false; }... }
29
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 29 Dining Philosophers: Java Solution, cont’d public class Philosopher extends Thread {... public void run() { snooze(); while (eatThink) { try { monitor.getForks(id); snooze(); monitor.releaseForks(this.id()); snooze(); } catch (Exception ex) { ex.printStackTrace(); } } }... } When started, every thread runs this method. Time to get seated at the table. Eat and think until it’s time to go home. Get forks and eat for a while. Release forks and think for a while.
30
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 30 Dining Philosophers: Java Solution, cont’d public class ForkMonitor { private boolean forks[]; private Philosopher philosophers[]; public ForkMonitor(Philosopher philosophers[]) { forks = new boolean[philosophers.length]; for (int i = 0; i < forks.length; i++) { forks[i] = true; } this.philosophers = philosophers; }... } All forks are initially available.
31
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 31 Dining Philosophers: Java Solution, cont’d public class ForkMonitor { private boolean forks[]; private Philosopher philosophers[];... public synchronized void getForks(int id) throws Exception { int left = id; // left fork index int right = (id + 1)%forks.length; // right fork index while (!forks[left] || !forks[right]) { philosophers[id].changeState(!forks[left] ? Philosopher.State.WAIT_LEFT : Philosopher.State.WAIT_RIGHT); wait(); } forks[left] = false; forks[right] = false; philosophers[id].changeState(State.EATING); philosophers[id].ateAgain(); }... } Only one philosopher can be getting forks at a time. Try to get both left and right forks. Take forks and start eating. Wait for both forks to become available.
32
Department of Computer Science Spring 2014: February 19 CS 149: Operating Systems © R. Mak 32 Dining Philosophers: Java Solution, cont’d public class ForkMonitor { private boolean forks[]; private Philosopher philosophers[];... public synchronized void releaseForks(int id) throws Exception { int left = id; // left fork index int right = (id + 1)%forks.length; // right fork index forks[left] = true; forks[right] = true; philosophers[id].changeState(State.THINKING); notifyAll(); } } Demo Only one philosopher can be releasing forks at a time. Release forks and resume thinking. Notify any waiting philosophers that forks are now available.
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.