A BEAR, HONEY POT AND BEES Friendly bees are feeding a trapped bear by collecting honey for it. The life of the trapped bear is just eating and sleeping. The bees carry honey to a pot, one portion each bee each time until the pot is full. The size of the pot is H portions. When the pot is full, the bee that brought the last portion wakes up the bear. The bear starts eating and the bees wait until the bear has eaten all the honey and the pot is empty again. Then the bear starts sleeping and bees start collecting honey again. Using semaphores: (Exercise 3, problem 4) =================== process bee[i=1 to N] { while (true) { collect_honey(); into_pot(); # deposit one honey portion into the honey pot } } process bear { while (true) { sleep(); # wait until the pot is full empty_pot();# eat all the honey } } sem mutex = 1, # mutual exlusion pot_full = 0; # is the pot full of honey int portions; # portions in the pot procedure into_pot() { P(mutex); portions ++; if (portions = = H) V(pot_full); # let the bear eat else V(mutex); # let the next bee in to fill } procedure sleep (){ P(pot_full); } procedure empty_pot(){ # eat all honey portions =0; V(mutex); # let the bees start filling the pot again } ------------------------------------------------------------------------- Exercise 4, problem 6 /by Averell Using monitor process bee[i=1 to N] { while (true) { collect_honey(); call pot.into_pot(); } } process bear() { while (true) { call pot.sleep(); call pot.empty_pot(); } } monitor pot { int portions=0; cond pot_full, pot_empty; procedure into_pot() { while (portions==H) wait(pot_empty); # note while! portions=portions + 1; if (portions==H) signal(pot_full); } procedure sleep() { if (portions < H) wait(pot_full); # note if, does while cause problems } procedure empty_pot() { portions=0; signal_all(pot_empty) # wake all waiting bees to deposit honey } } Using message passing ======================= chan deposit(); # bees receive from this channel permission to deposit # only one message at a time => only one bee can deposit at a time chan wakeup(); # the bear waits for wakeup process bear (){ send deposit(); # to let the first bee deposit while (true) { receive wakeup(); eat_honey(); portions= 0; send deposit(); # yhdelle mehiläiselle } } process bee[i=1 to N] (){ while (true) { collect_honey(); receive deposit() portions ++; if (portions== H) send wakeup(); # pot is full, wakeup bear else send deposit(); # let the next bee deposit its honey } } By using a server ( the same way as a monitor) ================================= chan into_pot(int id), # mehiläisiltä: haluaa tallettaa keräämänsä hunajan reply[i =1 to n] (),# mehiläisille: into_pot tehty, voi jatkaa wakeup (), # karhulle: herää hyömään, purkki on täynnä empty (); # karhulta: purkki taas empty process pot { # server int id, # bee id portions=0; # portions in the pot while (true) { receive into_pot(id); portions ++; # lisätään portions yhdellä send reply[id](); # deposited into the pot, let the bee continue if (portions = =H) { # pot is full portions =0; # mark it empty send wakeup(); # wake up the bear receive empty(); # wait for the bear to empty the pot } } } process bee[i=1 to N]() { while (true) { collect_honey(); send into_pot(i); # request to deposit receive reply[i](); # deposit done } } process bear () { while(true){ receive wakeup(); # sleep until the wakeup message arrives empty_honeypot(); send empty(); # inform the server that the pot is empty } } Entä, jos olisi 3 erilaista palvelupyyntöä (kuten monitorissa)? chan pyyntö(), # mehiläisiltä tai karhulta # kolme palvelupyyntötyyppiä: 0 = mehiläinen haluaa tallettaa 1 = karhu pyytää herätystä 2 = karhu pyytää hunajan syömistä (syöttämistä) reply[i=1 to N] (), # mehiläisille: into_pot tehty saa jatkaa keräämistä ok-Karhu; # karhun pyyntö täytetty Using rendezvous (Rendezvous huolehtii karhun herättämisestä) ======================= module Control_Pot op into_pot(), sleep(), empty_pot(); body process Buffer { int portions; while(true){ in into_pot() and portions < MAXSIZE -> portions++; [] sleep() and portions == MAXSIZE -> ; [] empty_pot() and portions == MAXSIZE -> portions=0; ni } end Control_pot process bee[i=1 to N] { while (true) { collect_honey(); call Control_pot.into_pot(); } } process bear() { while (true) { call Control_pot.sleep(); call Control_pot.empty_pot() } } Using RPC (vertaa semafori ratkaisu) ========= module Remote_pot op into_pot(), sleep(); body int portions; sem mutex=1 pot_full=0; proc into_pot() { P(mutex); portions++; if (portions==MAXSIZE) V(pot_full) # let the bear eat else V(mutex); # open the mutex for the next bee } proc sleep() { P(pot_full); } proc empty_pot() { portions=0; V(mutex); } process bee[i=1 to N] { while (true) { collect_honey(); call Remote_pot.into_pot(); # deposit one honey portion } } process bear { while (true) { call Remote_pot.sleep(); # wait until the pot is full call Remote_pot.empty_pot();# eat all the honey } }