###### tags: `prir` `studia` # Problem ucztujących filozofów Klasyczny problem synchronizacji - pięciu filozofów - 5 talerzy - 5 widelców - każdy filozof potrzebuje dwóch widelców żeby jeść (musi wziąć jednego z prawej i jednego z lewej) - w danym momencie kazdy może podnieść jeden widelec, nie może dwóch na raz > Jednocześnie może jeść maksymalnie dwóch filozofów którzy nie siedzą koło siebie (dla reszty zabraknie widelców) ## Rozwiązanie naiwne - które NIE DZIAŁA ``` Semaphore widelec[..4] = [(1, {})] -> FILOZOF[i] loop { mysl() wait(widelec[i]) wait(widelec[i+1]%5) jedz() signal(widelec[i]) signal(widelec[i+1]%5) } ``` **Dochodzi do zagłodzenia!** ## Rozwiązanie ograniczające miejsca - poprawne ``` Semaphore widelec[0..4] = [(1, {})] Semaphore sa_miejsca = (4, {}) -> FILOZOF[i] loop { mysl() wait(sa_miejsca) wait(widelec[i]) wait(widelec[i+1]%5) jedz() signal(widelec[i]) signal(widelec[i+1]%5) signal(sa_miejsca) } ``` ## Rozwiązanie asymetryczne - podobne do naiwnego, ale łamiemy cykl podniesień widelca ``` Semaphore widelec[0..4] = [{1, ()}] -> FILOZOF[i] int p,q if (i==0) p=(i+1)%5, q=i else p=i, q=(i+1)%5 loop { mysl() wait(widelec[p]) wait(widelec[q]) jedz() signal(widelec[p]) signal(widelec[q]) } ``` ## Rozwiązanie asymetryczne z użyciem monitora ``` monitor WidelceFilozofow { int widelce[0..4]; Condition mozeJesc[0..4] void podnies(int filozof) { if (widelce[filozof] < 2) wait(mozeJesc[filozof]) int prawy = (filozof-1)%n int lewy = (filozof+1)%n --widelce[prawy] --widelce[lewy] } void poloz(int filozof) { int prawy = (filozof-1)%n int lewy = (filozof+1)%n ++widelce[prawy] ++widelce[lewy] if (widelec[prawy] == 2) signal(mozeJesc[prawy]) if (widelec[lewy] == 2) signal(mozeJesc[lewy]) } } ```