Semafory 5R]ZL]DQLHSUREOHPXZ]DMHPQHJRZ\NOXF]DQLD %H]GRGDWNRZHJRZVSDUFLDVSU]WRZHJRLSURJUDPRZHJR =DNáDGDP\MHG\QLH*H]DSLVGRLRGF]\W]SDPLFLZVSyOQHMV RSHUDFMDPLDWRPRZ\PLF]\OLLVWQLHMHDUELWHUZVSyOQHMSDPLFL :UD]LHMHGQRF]HVQHJR]DSLVXLRGF]\WXUH]XOWDWHPEG]LH SU]HSOHFHQLHW\FKGZyFKLQVWUXNFMLZGRZROQHMNROHMQRFL Algorytm Dekkera üzlf]hqld Wada: ]ár*rqrü - aktywne oczekiwanie =GRGDWNRZ\PZVSDUFLHPVSU]WRZ\P 6SHFMDOQDLQVWUXNFMDPDV]\QRZDUHDOL]XMFDDWRPRZ\]DSLVL odczyt, np. var G: integer := 0; process P (i:integer); var Li: integer; sekcja_lokalna(i); Test_and_Set (Li) Li := G; G := 1; end // G - globalna dla wszystkich procesów // Li - lokalna dla procesu i // Wada - aktywne oczekiwanie Test_and_Set(Li); exit when Li = 0; end sekcja_krytyczna(i); G := 0; end Wsparcie programowe: semafory, monitory itp.
Definicja (klasyczna) semafora 6HPDIRUMHVW]PLHQQFDáNRZLWROLF]ERZSU]\MPXMFZDUWRFL QLHXMHPQHGODNWyUHMVRNUHORQHW\ONRQDVWSXMFHRSHUDFMH inicjacja, wait (lub P), signal (lub V),QLFMDFMDF]\OLQDGDQLHZDUWRFLSRF]WNRZHMMHVWZ\NRQ\ZDQH tylko raz dla danego semafora i poza procesami 2SHUDFMH3L9VQLHSRG]LHOQHLZ]DMHPQLHZ\NOXF]DMFHVL (dla danego semafora) P(S): gdy S > 0, to S := S -1, wpp proces jest zawieszany w oczekiwaniu na ten warunek V(S): S := S + 1 Oczekiwanie jest sprawiedliwe Definicja (praktyczna) semafora 36MHOL6!WR6 6ZSSZVWU]\PDMG]LDáDQLH SURFHVXZ\NRQXMFHJRWRSHUDFM 96MHOLVSURFHV\ZVWU]\PDQHZZ\QLNX36WRZ]QyZ jeden z nich, wpp S := S + 1 Semafor binarny Jest szczególnym przypadkiem semafora ogólnego - przyjmuje MHG\QLHZDUWRFLLOXEWUXHLIDOVH 3%L9%VUyZQLH*QLHSRG]LHOQHLZ]DMHPQLHZ\NOXF]DMFHVL W definicji semafora ogólnego S := S + 1 przechodzi na S := 1; S := S - 1 przechodzi na S := 0 (Uwaga: w niektórych implementacjach wykonanie VB(S) dla 6 NRF]\VLEáGHP 5R]ZL]DQLHSUREOHPXVHNFMLNU\W\F]QHMLQLFMDOQLH6 PB(S); sekcja_krytyczna(i); VB(S)
5y*QHXZDJL P - Passeren, Proberen; V - Vrijmaken, Verhohen (Dijkstra jest Holendrem) 1LHZROQRWHVWRZDüZDUWRFLVHPDIRUD39LLQLFMDFMDWR JEDYNE dopuszczalne operacje!) 2SHUDFMHVHPDIRURZHZ\NOXF]DMVLZ]DMHPQLHWDNMDN]DSLVL RGF]\W]WHMVDPHMNRPyUNLSDPLFL-HGQRF]HVQH*GDQLD Z\NRQDQLDRSHUDFMLQDW\PVDP\PVHPDIRU]HEGZ\NRQDQH VHNZHQF\MQLHZQLH]QDQHMNROHMQRFL:GHILQLFMLVHPDIRUDQLH PyZLVLNWyU\]]DZLHV]RQ\FKSURFHVyZ]RVWDQLHZ]QRZLRQ\ LPSOHPHQWDFMDPR*HDOHQLHPXVLZ]QDZLDüSURFHV\]JRGQLH] ]DVDGNROHMNLSURVWHM*\ZRWQRü VSUDZLHGOLZRü,PSOHPHQWDFMDVHPDIRUD]Z\NOHQDSR]LRPLHMGUDV\VWHPX operacyjnego, bez aktywnego oczekiwania Symulacja semaforów ogólnych binarnymi ZJNVL*NL6KDZD:17VWU Ä.D*G\VHPDIRURJyOQ\6PR*HE\ü]DVWSLRQ\SU]H]]PLHQQ FDáNRZLWN s i dwa semafory binarne mutex s i delay s 'ODND*GHM RSHUDFML36VWRVXMHVLZyZF]DV P(mutex s ); N s := N s - 1; if N s -1 then V(mutex s ); P(delay s ) end else V(mutex s ).D*GD]DRSHUDFMD96MHVW]DVWSRZDQDSU]H] P(mutex s ); N s := N s + 1; if N s 0 then V(delay s ); V(mutex s ) 3RF]WNRZRmutex s = 1, delay s = 0, a zmienna N s przyjmuje SRF]WNRZZDUWRü]PLHQQHMVHPDIRURZHM6 Czy ta symulacja jest zawsze poprawna?
=DNáDGDP\NODV\F]QGHILQLFMVHPDIRUD P1 P2 P3 P4 Poprawka Shawa P(m s ); 1 5 9 13 P(m s ); N s := N s - 1; 2 6 10 14 N s := N s - 1; if N s -1 then 3 7 11 15 if N s -1 then V(m s ); 12 16 V(m s ); P(d s ) P(d s ) end end; else V(m s ); 4 8 V(m s ); Sekcja krytyczna; P(m s ); 17 21 P(m s ); N s := N s + 1; 18 22 N s := N s + 1; if N s 0 then V(d s ); 19 23 if N s 0 then V(d s ) V(m s ) 20 else V(m s ) N s = 2 2:1 6:0 10:-1 14:-2 18:-1 22: 0 RSHUDFMDZDUWRü m s = 1 1:0 4:1 5:0 8:1 9:0 12:1 13:0 16:1 17:0 20:1 21:0 d s = 0 19:1 23:1!!! 3U]\NáDG3URGXFHQWLNRQVXPHQW]RJUDQLF]RQ\PEXIRUHP S: semaphore := 1; SHáQHSXVWHVHPDSKRUH 1^OLF]QLNLPLHMVFZEXIRU]H` process producent; produkuj; 3SXVWH^VSUDZG(F]\EXIRUPDPLHMVFD` P(S); wstaw; V(S); 9SHáQH^]ZLNV]HQLHOLF]QLNDSHáQ\FKPLHMVF` end
process konsument; 3SHáQH^VSUDZG(F]\EXIRUQLHMHVWSXVW\` P(S); pobierz; V(S); 9SXVWH^]ZLNV]HQLHOLF]QLNDSXVW\FKPLHMVF` konsumuj; end Inne rodzaje semaforów Semafor dwustronnie ograniczony (Lipton 74) P k (S): if S > 0 then S := S - 1 else czekaj V k (S): if S < k then S := S + 1 else czekaj Semafor OR (Lipton 74) P OR (S 1,..., S n ): if S 1 > 0... S n > 0 then S k :=S k - 1 else czekaj gdzie k = min{i: S i > 0} V OR (S k ): S k := S k + 1 Semafor AND (Patril 71) P AND (S 1,..., S n ): if S 1 > 0... S n > 0 then k S k := S k - 1 else czekaj V AND (S k ): S k := S k + 1 Semafor uogólniony (Lipton 74) P(S 1, t 1,..., S n, t n ): if S 1 t 1... S n t n then k S k := S k - t k else czekaj V (S 1, t 1,..., S n, t n ): k S k := S k + t k Semafor sparametryzowany (Presser 75) P(S 1, t 1, d 1,..., S n, t n, d n ): if S 1 t 1... S n t n then k S k := S k - d k else czekaj V (S 1, d 1,..., S n, d n ): k S k := S k + d k
Formalizm Habermanna 0R*OLZRüNRQW\QXDFMLSUDF\SU]H]GRZROQ\SURFHVSU]\ Z\NRQDQLXRSHUDFML3]DOH*\RGOLF]E\Z\NRQDQ\FKZ SU]HV]áRFLQDW\PVHPDIRU]HRSHUDFML3L9RUD]RGZDUWRFL SRF]WNRZHMVHPDIRUD Oznaczenia: &6ZDUWRüSRF]WNRZDVHPDIRUD6&6 0 Q96OLF]EDZ\NRQDRSHUDFML9QD6 Q3 6OLF]EDZ\ZRáDRSHUDFML3QD6F]\OLLOHUD]\SURFHV\ UR]SRF]á\RSHUDFM3 Q36OLF]EDSU]HMüSU]H]RSHUDFM3QD6F]\OLLOHUD]\ SURFHV\PRJá\NRQW\QXRZDüSUDFSRZ\NRQDQLX operacji P) Wówczas P(S): np (S) := np (S) + 1 if np (S) C(S) + nv(s) then np(s) := np(s) + 1 V(S): if np (S) > C(S) + nv(s) then np(s) := np(s) + 1 nv(s) := nv(s) + 1 Twierdzenie np(s) = min (np (S), C(S) + nv(s)) MHVWQLH]PLHQQLNLHPZ\NRQDRSHUDFML3L9GRZyG indukcyjny) Semafory Agerwali (T. Agerwala, Some extended semaphore primitives, Acta Informatica, 1977, 8, 3) Idea: wprowadzenie jednoczesnych operacji semaforowych, w NWyU\FKZ\NRQDQLHRSHUDFMLW\SX3MHVWX]DOH*QLRQHRGVWDQX podniesienia lub opuszczenia wskazanych semaforów
PE(S 1,..., S n ; S n+1,..., S n+m ) powoduje zawieszenie procesu do chwili, gdy dla wszystkich S k N QEG]LHVSHáQLRQH6 k > 0 oraz dla wszystkich S i L QQPEG]LHVSHáQLRQH6 i = 0; for i := 1 to n do S i := S i - 1 VE(S 1,..., S r ): for i := 1 to r do S i := S i + 1 S k (k = 1,...,n); S i (i=n+1,...,n+m); S t W UVVHPDIRUDPL 6HPDIRU\$JHUZDOLSR]ZDODMQDLQG\ZLGXDOQHWUDNWRZDQLH ZVSyáSUDFXMF\FK]HVRESURFHVyZDZLFQD]ZL]DQLH]QLPL SULRU\WHWyZSRG]LDáQDUR]áF]QHNODV\]HZ]JOGXQDSULRULWS 3ULRU\WHWRZ\GRVWSGR]DVREyZQDOH*\]V\QFKURQL]RZDü GRVWS1SURFHVyZGR]DVREX5'RVWSPDE\üUHDOL]RZDQ\ ZHGáXJSULRU\WHWyZSURFHVyZQL*V]DZDUWRüZ\*V]\ priorytet) var S: array[1..n] of semaphore := (0,...,0); T: semaphore := 1; R: resource; process P (prio: 1..N) var k: 0..N; k := prio - 1; praca bez zasobu; VE(S[prio]); if k = 0 then PE(T) else PE(T; S[1],..., S[k]); PE(S[prio]); VHNFMDNU\W\F]QD]X*\FLHP5 VE(T) end end; co P(1);... ; P(N) coend.
3UREOHPSLFLXILOR]RIyZUR]ZL]DQLH]VHPDIRUDPL 5R]ZL]DQLH w: array[0..4] of semaphore := (1,1,1,1,1) {widelce} process F (i:0..4) P\OL P(w[i]); P(w[(i+1) mod 5]); je; V(w[i]); V(w[(i+1) mod 5]); end end; 0R*OLZRü]DVWRMX 5R]ZL]DQLH w: array[0..4] of semaphore := (1,1,1,1,1) {widelce} j: semaphore := 4; {jadalnia} process F (i:0..4) P\OL P(j); P(w[i]); P(w[(i+1) mod 5]); je; V(w[i]); V(w[(i+1) mod 5]); V(j) end end; &]\NROHMQRüRSHUDFML3MHVWGRZROQD" &]\NROHMQRüRSHUDFML9MHVWGRZROQD" - Super rejon krytyczny
5R]ZL]DQLH LW\ILOR]RIP\OL V>L@ LW\ILOR]RIMHVWJáRGQ\ 2 i-ty filozof je s: array[0..4] of 0..2 := (0,0,0,0,0) {stan} m: semaphore := 1; {mutex} ps: array[0..4] of semaphore := (0,0,0,0,0) {prywatny sem} procedure test (k: 0..4); if s[k] = 1 and s[(k-1) mod 5] 2 and s[(k+1) mod 5] 2 then s[k] := 2; V(ps[k]) end end; {test} process F (i:0..4) P\OL P(m); s[i] := 1; test(i); V(m); P(ps[i]); je; P(m); s[i] := 0; test((i-1) mod 5]); test((i+1) mod 5]); V(m) end end; 0R*OLZRü]DJáRG]HQLD
Semafory w systemie Unix Operacje na pojedynczym semaforze 36QRSXV]F]HQLH6RZDUWRüQ 96QSRGQLHVLHQLH6RZDUWRüQ =6F]HNDMD*6 Q36QQLHEORNXMFHRSXV]F]HQLH6RZDUWRüQ Q96QQLHEORNXMFHSRGQLHVLHQLH6RZDUWRüQ Operacje jednoczesne >9636=6@F]HNDMD*6 3 oraz S3 = 0 i wtedy 6]ZLNV]RD6]PQLHMV]R >Q36=696@MHOL6 1 i S2 = 0, to zmniejsz S1 RL]ZLNV]6RZSSQLFQLHUyEQLHEORNXMFD 2SHUDFMHQLHEORNXMFHGDMZZ\QLNXZDUWRüORJLF]Qtrue, JG\RSHUDFMDVLSRZLRGáDLfalse wpp Funkcje na semaforach ZDUW6ZDUWRüVHPDIRUD6 F]HN36OLF]EDSURFHVyZF]HNDMF\FKQD36 F]HN=6OLF]EDSURFHVyZF]HNDMF\FKQD=6 8ZDJDZM]\NX&]DSLVXMHVLWRLQDF]HM