I've encountered the dining savages problem and solution, but I don't seem to understad how the solution is handling the situation when a savage tries to eat from the pot while it's still empty. The problem and solution from the little book of semaphores:
A tribe of savages eats communal dinners from a large pot that can hold M servings of stewed missionary. When a savage wants to eat, he helps himself from the pot, unless it is empty. If the pot is empty, the savage wakes up the cook and then waits until the cook has refilled the pot. Any number of savage threads run the following Unsynchronized savage code:
while True :
getServingFromPot()
eat()
And one cook thread runs this Unsynchronized cook code:
while True:
putServingsInPot(M)
The synchronization constraints are:
- Savages cannot invoke getServingFromPot if the pot is empty.
- The cook can invoke putServingsInPot only if the pot is empty.
Puzzle: Add code for the savages and the cook that satisfies the synchronization
Solution (cook):
while True:
emptyPot.wait()
putServingsInPot(M)
fullPot.signal()
Solution (savages):
while True:
mutex.wait()
if servings == 0:
emptyPot.signal ()
fullPot.wait ()
servings = M
servings -= 1
getServingFromPot ()
mutex.signal()
eat()
My question - when we first reach servings = 0
, after M savages ate form the pot, we get to emptyPot.signal()
and then fullPot.wait()
- Both semaphores; then, from my point of view there might be a corner case where we may get to getServingsFromPot
before the cook has the chance to get context and fill the pot. Am I missing something?
CodePudding user response:
I'm assuming that signal
and wait
are the usual V and P semaphore operations.
I think you might be missing the point of each semaphore.
emptyPot
: cook will not fill the pot unless a savage has signaled that the pot it empty;fullPot
: the savage who signaled that the pot is empty will not get a serving unless the cook has signaled that the pot is full;mutex
: a savage who wants to eat will not proceed unless another savage has signaled that they're done serving themselves.
Therefore:
- multiple savages can be eating at the same time;
- no two savages will try to serve themselves at the same time;
- a savage will not try to serve themselves if the pot is empty;
- after waking up the cook, a savage will not try to serve themselves unless the pot is full.
Thus, there can be no race condition. Due to calling fullPot.wait()
, a savage cannot get to getServingsFromPot
until the cook has woken up, filled the pot and called fullPot.signal()
.