1 / 19

Solution to the Dining Philosophers Problem

Solution to the Dining Philosophers Problem. Prepared by Tushar Abhishek (11CS10047). Dining Philosophers Problem. Formulated by E. Dijkstra (1965). An overview A standard problem to address synchronization issues in concurrent algorithm design.

regina
Download Presentation

Solution to the Dining Philosophers Problem

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Solution to the Dining Philosophers Problem Prepared by Tushar Abhishek (11CS10047)

  2. Dining Philosophers Problem • Formulated by E. Dijkstra (1965). • An overview • A standard problem to address synchronization issues in concurrent algorithm design. • N philosophers are seated around a table with a bowl of food in front of them and N forks – each one shared by two adjacent philosophers. • Each philosopher alternates between eating and thinking – they must acquire the forks to their left and right to eat.

  3. Dining Philosophers’ Problem Here the number of philosophers (or whatever they are) is 5 Image Source: http://cs.stanford.edu/people/eroberts/courses/soco/projects/1998-99/randomized-algorithms/pics/dining_philosophers.gif

  4. Solutions • Until now, we have seen three solutions to the problem. But each of them have downsides. • First solution: • Naïve solution: Each philosopher takes the forks one by one if they are available and puts them down after use. Procedure of taking the fork will block if the fork is not available. The processes of checking and taking are not atomic hence a well timed context-switch can compromise the robustness of the algorithm.

  5. Solutions • Second Solution: • Now each fork has an associated semaphore. This ensures mutual exclusion during access of each fork. But the process of taking both left and right fork is still non-atomic. Hence if everyone takes one (e.g. left) of the forks, each one has to wait indefinitely for the other fork (which is held by the next philosopher, who, in turn, is waiting for yet another one). This kind of situation is known as deadlock. • In light of the above problem, a slight modification was introduced in the algorithm. Now, a philosopher puts down the fork if the other one is not available. Again, this can create another problem if all of them simultaneously take forks and put them down, doing so repeatedly for an indefinite time. This kind of situation is known as starvation.

  6. Solutions • Third Solution: • In this solution only one philosopher is allowed to take forks, eat and put the forks down at a time. This ensures mutual exclusion and the whole action is now atomic, but this solution is inefficient in terms of resources – a philosopher on the opposite side of the table will starve even if both the forks at his side are free.

  7. Final Solution • Now that we have seen the problems with the previous solutions, we are ready to propose the final solution that is deadlock/starvation-free as well as ensures maximum parallelism. • We maintain two arrays – • state: An array of integers that identify the current state of each philosopher. • States are THINKING, HUNGRY, EATING • s: An array of semaphores (initialized to zero) – one for each fork. • Also, a semaphore mutex (initialized to one), which ensures mutual exclusion when accessing the state of philosophers.

  8. void Philosopher(i) { repeat { Think(); Take_forks(i); // take forks at own side Eat(); Put_forks(i); // put forks at own side } }

  9. void Take_forks(i) { Down (&mutex); // critical section starts state[i] = HUNGRY; // set own state to hungry Test(i); // check if forks are free Up(&mutex); // critical section ends Down(&s[i]); // own forks are occupied }

  10. void Put_forks(i) { Down(&mutex); // critical section starts state[i] = THINKING; // set own state to thinking Test(LEFT); // pass left fork Test(RIGHT); // pass right fork Up(&mutex); // critical section ends }

  11. void Test(i) { if(state[i] == HUNGRY AND state[LEFT] != EATING AND state[RIGHT] != EATING) { state[i] == EATING; // ith one can eat now Up(&s[i]); // forks can be taken } }

  12. Walk-through • We consider two cases: • Case 1: No adjacent philosophers are eating. • Enter critical section to take the forks (if none of the rest are accessing states). • Set own state to hungry. • Test the states of the adjacent philosophers. • None of them are eating, set state to eating, raise s[i]. • Exit critical section and lower s[i] (no effect since s[i] = 1). • Eat. • Enter critical section to put the forks down. • Set own state to thinking. • Test the states of adjacent philosophers one by one. • Pass the forks if the corresponding philosopher is hungry and the next one is not busy eating (i.e. when both forks are accessible). • Raise corresponding s and exit critical section.

  13. Walk-through • Case 2: At least one of the philosophers is busy eating. • Enter critical section to take the forks (if none of the rest are accessing states). • Set own state to hungry. • Test the states of the adjacent philosophers. • On finding that an adjacent philosopher is eating, exit critical section and lower s[i] (gets blocked as a result since s[i] = 0). • Meanwhile the eating philosopher finishes eating and tests the states raising s[i] as a result. The waiting philosopher can now continue as before.

  14. Conclusion • This solution is free of deadlock and starvation. • This solution ensures maximum parallelism.

  15. Sleeping Barber Problem • Formulated by E. Dijkstra (1965). • An overview • A classic problem which addresses synchronization issues in inter-process communication. • A barber maintains a shop with a waiting room having a limited number of chairs. The barber serves a customer and then looks for next customer in the waiting room. If there are no more customers in the waiting room, s/he sleeps. • A customer enters the shop and looks for the barber. If the barber is sleeping, s/he is woken up by the customer who is then served by the barber. If the barber is busy serving someone else, the customer goes to the waiting room. If there is an empty chair, s/he waits for the barber. Otherwise if the waiting room is full, s/he leaves.

  16. Sleeping Barber Problem • Some issues when dealing with the problem. • A customer, on finding the barber busy, sets off for the waiting room, which currently is empty. Meanwhile, the barber finishes the service and looks in the waiting room. S/he finds the waiting room empty (the customer has not reached yet), and goes to sleep. The customer arrives and waits till the next customer comes since the barber is asleep and no one is there to wake him/her up. (Wastage of time). It may also happen that the customer in question is the last one, and hence waits indefinitely (Deadlock). • The waiting room has got one free chair remaining and more than one customer are trying to access the chair. (Race condition).

  17. Proposed Solution • waiting: A shared integer to keep track of waiting customers. • Three semaphores • C: Is barber asleep? (Customer wakes the barber up if it so) • B: Is barber busy? (Customer waits if it is so) • mutex: Ensures mutual exclusion when accessing waiting.

  18. void barber() { repeat { Down(&C); // sleep if no customers Down(&mutex); // critical section starts waiting--; // one less customer left Up(&B); // barber available Up(&mutex);// critical section ends Cut_hair(); // perform action } }

  19. void customer() { Down(&mutex); // critical section starts if(waiting < chairs) { // free chairs waiting++; // one more customer added Up(&C); // wake up barber if needed Up(&mutex); // critical section ends Down(&B); // wait if barber is busy Get_haircut(); // perform action } else Up(&mutex); // exit c. section, leave }

More Related