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 i s 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: ================= sem mutex = 1, # mutual exlusion pot_full = 0; # is the pot full of honey int portions = 0; # 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 } 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 } } Using monitor ============= monitor pot { int portions=0; cond pot_full, pot_empty; procedure into_pot() { # note while! while (portions==H) wait(pot_empty); portions=portions + 1; if (portions==H) signal(pot_full); } procedure sleep() { # note if! Does while cause problems? if (portions < H) wait(pot_full); } procedure empty_pot() { portions=0; signal_all(pot_empty) # wake all waiting bees to deposit honey } } 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(); } } 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 } } Using a server ( the same way as a monitor) =========================================== chan into_pot(int id), # mehiläisiltä: haluaa tallettaa hunajan reply[i =1 to n](),# mehiläisille: # into_pot tehty, voi jatkaa wakeup (), # karhulle: herää hyömään empty (); # karhulta: purkki taas tyhjä process pot { # server int id, # bee id portions=0; # portions in the pot while (true) { receive into_pot(id); portions ++; # one portion more send reply[id](); # deposit done 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(); # wait for the wakeup empty_honeypot(); send empty(); # inform the server } } 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ää syömistä (syöttämistä) chan 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 < H -> portions++; [] sleep() and portions == H -> ; [] empty_pot() and portions == H -> 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==H) V(pot_full) # let bear eat else V(mutex); # open 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 honey } } process bear { while (true) { call Remote_pot.sleep(); # wait for full pot call Remote_pot.empty_pot();# empty the pot } }