SEMAFORY Dominik Niewiadomy Łukasz Dąbrowski
Proces Programy współbieżne - program w trakcie wykonywania, jednostka pracy w systemie z podziałem czasu; procesor wykonuje je sekwencyjnie, w dowolnej chwili na zamówienie procesu może być wykonywany jeden rozkaz kodu programu - program w trakcie wykonywania, jednostka pracy systemu operacyjnego. W skład procesu wchodzi chroniona przez system operacyjny przestrzeń adresowa mieszcząca m. in. instrukcje programu, dane programu i stos. - do procesu należą zawartości rejestrów maszynowych, tablica otwartych plików i inne struktury danych określające jego aktualne zasoby. Proces jest tworem aktywnym i dynamicznym, każdy proces zawiera co najmniej jeden sekwencyjny wątek sterowania, określany w każdej chwili przez stan licznika rozkazów. W niektórych systemach operacyjnych proces może zawierać wiele wątków. Programy współbieżne - każdy program wykonywany w systemie wieloprogramowym, program, który tworzy własne podprocesy i koordynuje ich współpracę, np. program wielowątkowy program wykonywany równolegle z innymi programami w systemie wieloprocesorowym lub rozproszonym , program równoległy współbieżność wymaga współpracy między procesami i dostępu do mechanizmów, umożliwiających procesom wzajemne komunikowanie się i synchronizacje działań.
Podział czasu Jednoczesność sposób realizowania wieloprogramowości, stosowany w systemach interakcyjnych, w którym planista procesora (najważniejsza z procedur planujących wieloprogramowego systemu operacyjnego, odpowiedzialna za wybieranie procesów z kolejki procesów gotowych do działania) dzieli czas procesora równomiernie między zainteresowane procesy. Każdy proces otrzymuje okresowo małą porcję czasu, zwaną kwantem i jeśli nie zakończy działania w ramach przydzielonego kwantu, to zostaje wywłaszczony z procesora. Jednoczesność W przypadku systemu jednoprocesorowego “jednoczesność” osiąga się za pomocą podziału czasu, w systemach wieloprocesorowych jednoczesność wykonywania wielu programów może być rzeczywista. Przez wykonywanie bezpieczne rozumie się sprzętową ochronę procesów systemów wieloprogramowych przed wzajemnymi zaburzeniami. Równoległość - rzeczywista jednoczesność działań, uzyskiwana w środowisku wieloprocesorowym, w odróżnieniu od współbieżności, realizowanej także w systemach jednoprocesorowych.
Synchronizacja - uzgadnianie kolejności powiązanych ze sobą działań różnych procesów lub uzależnianie wykonywania działań od sygnałów zegarowych. Synchronizacja jest jednym z podstawowych zagadnień organizacji systemów komputerowych. Komunikacja międzyprocesowa - zespół środków umożliwiających wymianę komunikatów między procesami wykonywanymi w jednej maszynie. Wątek - lub proces lekki to podstawowa jednostka wykorzystania procesora, o składzie : licznik rozkazów, zbiór rejestrów, obszar stosu.
zasób nadającego się do wspólnego użytkowania przez wiele procesów. Zasób dzielony zasób nadającego się do wspólnego użytkowania przez wiele procesów. Sekcja krytyczna fragment kodu, który powinien być wykonany z zachowaniem niepodzielności, tj. jednoetapowo, bez przerwań. Brak ochrony wykonywania sekcji krytycznej może powodować nieokreślone skutki w działaniu oprogramowania. Obsługę sekcji krytycznej organizuje się w procesach np. za pomocą semaforów,jest to obszar programu składający się z instrukcji, które może wykonywać tylko określona liczba procesów.
Wzajemne wyłączanie, wzajemne wykluczanie - rodzaj synchronizacji polegającej na niedopuszczaniu do jednoczesnego korzystania przez dwa procesy z tego samego zasobu. Niektóre zasoby są konstrukcyjnie niepodzielne, np. drukarki, więc korzystanie z nich musi odbywać się na zasadach wzajemnego wyłączania. Także niektóre operacje na zasobach dzielonych muszą podlegać wzajemnemu wyłączaniu, dotyczy to np. niektórych przypadków operacji pisania na dysku. Jeżeli jeden procesem działa w swojej sekcji krytycznej to inny proces nie jest dopuszczony do swojej sekcji krytycznej.Wykonywanie sekcji krytycznych polega na wzajemnym wykluczaniu się.
Semafor – abstrakcyjny typ danych wraz z operacjami umożliwiającymi wstrzymywanie i wznawianie procesów. Na semaforze oprócz określania jego stanu początkowego można wykonać tylko dwie operacje: Podniesienie semafora V(S) Opuszczenie semafora P(S) o których zakłada się, że są niepodzielne, czyli że w danej chwili może być wykonana jedna z nich.
RODZAJE SEMAFORÓW : Semafor ogólny Semafor binarny
Semafor ogólny: (wg Dijkstry) Semafor ogólny to zmienna całkowita z dwoma wyróżnionymi operacjami: Podniesienie semafora to instrukcja - S:=S+1 Opuszczenie semafora to instrukcja czekaj aż S>0; - S:=S-1
Semafor ogólny: (wg Ben-Ari) Opuszczenie semafora to instrukcja jeśli S>0, to S:=S-1, w przeciwnym razie wstrzymaj działanie procesu wykonującego tę operację Podniesienie semafora to instrukcja jeśli są procesy wstrzymane w wyniku wykonania operacji opuszczenia semafora S to wznów jeden z nich, w przeciwnym razie S:=S+1
Semafor binarny: Nie jest zmienną całkowitą, lecz zmienną logiczną (pojedynczym bitem) i może przyjmować tylko wartości 0 i 1 (true lub false)
Definicja klasyczna: Podniesienie semafora to instrukcja S:=1 Opuszczanie semafora to instrukcja czekaj, aż S=1; S:=0
Definicja praktyczna: Podniesienie semafora to instrukcja jeśli są procesy wstrzymane w wyniku wykonania operacji opuszczania semafora S, to wznów jeden z nich, w przeciwnym razie S:=1 Opuszczanie semafora to instrukcja jeśli S=1, to S:=0, w przeciwnym razie wstrzymaj działanie procesu wykonującego tę operację
Przykłady: Wzajemne wykluczanie Producenci i konsumenci Czytelnicy i pisarze Pięciu filozofów
Wzajemne wykluczanie Gdy procesy współbieżne do wzajemnej komunikacji używają wspólnej pamięci, wyniki takiej komunikacji mogą okazać się przypadkowe. Prawidłowa komunikacja współbieżnych procesów przez wspólny obszar pamięci wymaga dotrzymania warunku wzajemnego wykluczania Wzajemne wykluczanie - wymaganie aby ciąg operacji na pewnym zasobie (zwykle pamięci) był wykonany w trybie wyłącznym przez tylko jeden z potencjalnie wielu procesów.
Wzajemne wykluczanie const N = ?; {liczba procesów} var S: binary semaphore := 1; process P(i:1..N); begin while true do begin własne_sprawy; PB(S); sekcja_krytyczna; VB(S) end end;
Czytelnicy i pisarze Problem czytelników i pisarzy to problem dostępu do zasobów. Pisarze to procesy które korzystają z zasobu indywidualnie. Czytelnicy mogą korzystać wspólnie. Rozwiązanie problemu bez zagłodzenia którejkolwiek ze stron polega na tym, że ostatni wychodzący czytelnik przekazuje dostęp do czytelni pierwszemu czekającemu pisarzowi (chyba że takiego nie ma). Pisarz wychodząc z czytelni wpuszcza wszystkich czekających czytelników. Nowi czytelnicy mogą również później wchodzić pod warunkiem że nie ma żadnego czekającego pisarza. W czytelni może przebywać dowolna ilość czytelników lub tylko jeden pisarz. Ten problem to "abstrakcja" dostępu do bazy danych.
Czytelnicy i pisarze const M = ?; {liczba czytelników} P = ?; {liczba pisarzy} var ac: integer := 0; {aktywni czytelnicy} dc: integer := 0; {działający czytelnicy} ap: integer := 0; {aktywni pisarze} ac: integer := 0; {działający pisarze} CZYT: semaphore := 0; {wstrzymuje czytelników} PIS: semaphore := 0; {wstrzymuje pisarzy} CHROŃ: binary semaphore := 1; {do ochrony zmiennych} W: binary semaphore := 1; {do wykluczania pisarzy}
Czytelnicy i pisarze process CZYTELNIK(i: 1..M); Begin while true do begin własne_sprawy; PB(CHROŃ); ac := ac + 1; if ap = 0 then while dc < ac do begin dc := dc + 1; {wpuszczenie wszystkich} V(CZYT) {czytelników przed sobą} end; {i otwarcie sobie drogi} VB(CHROŃ); P(CZYT); czytanie;
Czytelnicy i pisarze PB(CHROŃ); dc := dc – 1; ac := ac – 1; if dc = 0 then while dp < ap do begin dp = dp + 1; {wpuszczenie wszystkich} V(PIS) {oczekujących pisarzy} end; VB(CHROŃ) End; End
Czytelnicy i pisarze process PISARZ(i: 1..P); Begin while true do begin własne_sprawy; PB(CHROŃ); ap := ap + 1; if ac = 0 then while dp < ap do begin {tu mógłby być if} dp := dp + 1; {ale dla symetrii jest} V(PIS) {instrukcja while} end; VB(CHROŃ); P(PIS); PB(W); pisanie;
Czytelnicy i pisarze VB(W); PB(CHROŃ); dp := dp – 1; ap := ap – 1; if dp = 0 then while dc < ac do begin dc = dc + 1; {wpuszczenie wszystkich} V(CZYT) {oczekujących czytelników} end; VB(CHROŃ) End; End
Czytelnicy i pisarze const M = ?; {liczba czytelników} P = ?; {liczba pisarzy} var WOLNE: semaphore := M; {liczba miejsc} W: binary semaphore := 1; {do wzajemnego wykluczania pisarzy} process CZYTELNIK(i: 1..M); Begin while true do begin własne_sprawy; P(WOLNE); czytanie; V(WOLNE) end End;
Czytelnicy i pisarze process PISARZ(i: 1..P); var j: integer; Begin while true do begin własne_sprawy; PB(W); for j := 1 to M do P(WOLNE); pisanie; for j := 1 to M do V(WOLNE); VB(W) end End;
Pięciu filozofów
Pięciu filozofów Założenia Filozof będzie miał w danym momencie do dyspozycji 2 widelce; Żaden z 5 filozofów nie będzie czekał w nieskończoność; Jeśli filozof podniósł już oba widelce, to w skończonym czasie naje się i odłoży je na stół; Rozwiązanie nie może wyróżniać żadnego z filozofów (algorytmy wszystkich pięciu filozofów dotyczące podnoszenia i odkładania muszą być takie same). Zakłada się kolejność podnoszenia sztućców
Pięciu filozofów Rozwiązanie z możliwością zakleszczania Jest to najprostsze rozwiązanie tego problemu. Polega ono na sekwencyjnym obejmowaniu zasobów (podnoszeniu widelców) przez zgłodniałego filozofa. Po najedzeniu odkłada oba widelce na stół. Z punktu widzenia jednego filozofa jest to rozsądne postępowanie. Jednak ponieważ wszyscy oni postępują tak samo, łatwo wyobrazić sobie można sytuację, choć bardzo mało prawdopodobną, w której każdy chwyci za swój prawy widelec i będzie czekać na to, aż jego lewy sąsiad skończy jeść i odłoży widelec, może to nigdy nie nastąpić, gdyż lewy sąsiad czeka na to samo zdarzenie. Jest to typowy przykład zjawiska zakleszczenia, w którym uczestniczą wszystkie współdziałające wątki.
Pięciu filozofów Rozwiązanie asymetryczne Rozwiązanie to jest podobne do pierwszego rozwiązania. Różnica polega na kolejności podnoszenia widelców. Filozof o parzystym numerze podnosi najpierw widelec prawy a potem lewy, nieparzysty odwrotnie. Algorytm ten zapewnia niewystępowanie zakleszczeń, ale nie chroni przed głodzeniem. np.: Jeśli filozof A czeka na widelec. Właściciel widelca B może go odłożyć, ale nie jest zagwarantowane, czy filozof A go weźmie jeśli filozof B będzie chciał znowu jeść. Drugim problemem jest brak równości filozofów. Ponieważ filozof czwarty nie ma z kim konkurować o pierwszy widelec jest on najkrócej blokowany
Pięciu filozofów Rozwiązanie z lokajem. Okazuje się że sami filozofowie nie są w stanie rozwiązać problemu odżywiania się. Potrzebny jest jakiś zewnętrzny arbiter, rozstrzygający wedle ustalonego warunku w określonych sytuacjach. Arbitrem takim może być np. lokaj, który będzie dbał o to, aby w każdej chwili co najwyżej czterech filozofów konkurowało o widelce. Można łatwo wykazać, że wówczas przynajmniej jeden z nich mógł podnieść oba widelce i jeść.
Pięciu filozofów Rozwiązanie z monitorem Rozwiązanie to polega na tym że głodny filozof podnosi widelce gdy obydwa są wolne. Jeśli któryś z widelców jest zajęty to czeka. Rozwiązanie to nie jest całkowicie poprawne ponieważ może dojść do zagłodzenia któregoś z filozofów.
Pięciu filozofów var WIDELEC: array[0..4] of binary semaphore:= (1,1,1,1,1); process FILOZIF(i:0..4); Begin while true do begin myślenie; PB(WIDELEC[i]); PB(WIDELEC[(i+1) mod 5]); jedzenie; VB(WIDELEC[i]); VB(WIDELEC[(i+1) mod 5]); end End;
Pięciu filozofów var WIDELEC: array[0..4] of binary semaphore:= (1,1,1,1,1); LOKAJ : semaphore := 4; process FILOZIF(i:0..4); Begin while true do begin myślenie; P(LOKAJ); PB(WIDELEC[i]); PB(WIDELEC[(i+1) mod 5]); jedzenie; VB(WIDELEC[i]); VB(WIDELEC[(i+1) mod 5]); V(LOKAJ) end End;
Jak wszyscy wiemy semafory są również stosowane w transporcie i komunikacji ale to nas akurat nie interesuje HAHAHA TO MIAŁO być śmieszne ale nie było...
Korzystaliśmy z: http://ciapek.uci.agh.edu.pl/~jroman/ http://studia.elka.pw.edu.pl/pub/SOP2A.A/w/w5.doc http://rainbow.mimuw.edu.pl/~mengel/MS/www9/ oraz materiałów wykładowych dr inż. J. Dokimuka