Programowanie współbieżne i rozproszone/PWR Ćwiczenia 5
Producenci i konsumenci
- Zadanie
Napisz w CSP rozwiązanie problemu producentów i konsumentów z jednym producentem, jednym konsumentem i jednym buforem jednoelementowym.
[ PRODUCENT:: p: porcja; *[true -> produkuj(p); BUFOR!p ] || KONSUMENT:: p: porcja; *[BUFOR?p -> konsumuj(p) ] || BUFOR:: p: porcja; *[PRODUCENT?p -> KONSUMENT!p ] ]
- Zadanie
Zmodyfikuj powyższe rozwiązanie tak, aby było wielu producentów.
[ PRODUCENT(i: 1..N):: p: porcja; *[true -> produkuj(p); BUFOR!p ] || KONSUMENT:: p: porcja; *[BUFOR?p -> konsumuj(p) ] || BUFOR:: p: porcja; *[(i: 1..N)PRODUCENT(i)?p -> KONSUMENT!p ] ]
- Zadanie
Zmodyfikuj rozwiązanie pierwszego zadania tak, aby był 1 producent i wielu konsumentów.
[ PRODUCENT:: p: porcja; *[true -> produkuj(p); BUFOR!p ] || KONSUMENT(i: 1..K):: p: porcja; BUFOR!Chce(); *[BUFOR?p -> konsumuj(p); BUFOR!Chce() ] || BUFOR:: p: porcja; *[PRODUCENT?p -> [(i:1..K)KONSUMENT(i)? Chce() -> KONSUMENT(i)!p] ] ]
- Zadanie
Napisz rozwiązanie problemu producentów i konsumentów z wieloma producentami, wieloma konsumentami i jednym M elementowym buforem cyklicznym.
[ PRODUCENT:: p: porcja; *[true -> produkuj(p); BUFOR!p ] || KONSUMENT:: p: porcja; *[true -> BUFOR!chcę(); BUFOR?p; konsumuj(p) ] || BUFOR:: bufor: (0..M-1) porcja; pozycja, ile: integer; (pozycja, ile) := (0,0); *[ile < M; PRODUCENT?bufor((pozycja + ile) mod M) -> ile := ile + 1 |ile > 0; KONSUMENT?chcę() -> KONSUMENT!bufor(pozycja); ile := ile - 1; pozycja := (pozycja + 1) mod M ] ]
Czytelnicy i pisarze
- Zadanie
Rozwiąż problem czytelników i pisarzy. Wykorzystaj w pełni synchroniczność mechanizmu CSP, unikając przesyłania potwierdzeń, gdy tylko jest to możliwe.
[ CZYTELNIK(i:1..C):: *[true -> CZYTELNIA!czytam(); czytanie(); CZYTELNIA!koniec_czytania() ] || PISARZ(i:1..P):: *[true -> CZYTELNIA!chcę_pisać(); CZYTELNIA?możesz_pisać(); pisanie(); CZYTELNIA!koniec_pisania() ] || CZYTELNIA:: czyt: integer; comment czyt - liczba czytaj±cych czytelników czyt := 0; *[(i:1..C) CZYTELNIK(i)?czytam() -> czyt := czyt + 1 |(i:1..C) CZYTELNIK(i)?koniec_czytania() -> czyt := czyt - 1 |(i:1..P) PISARZ(i)?chcę_pisać() -> *[(j:1..C) czyt > 0; CZYTELNIK(j)?koniec_czytania() -> czyt := czyt - 1 ]; PISARZ(i)!możesz_pisać(); PISARZ(i)?koniec_pisania(); ] ]
Turniej =
- Zadanie
W systemie działa arbiter i szesnastu graczy. Arbiter łączy graczy w pary zgodnie z kolejnością zgłoszeń, a następnie informuje kto z kim gra. Gra polega na wymianie losowych liczb (funkcja {\tt losuj()}). Wygrywa ten z graczy, który podał większą liczbę, w przypadku równych wartości wygrywa gracz o większym numerze. Zwycięzca przechodzi do następnej tury i zgłasza się ponownie do arbitra. W danej chwili mogą toczyć się rozgrywki w kilku turach. Po zakończeniu rozgrywek arbiter ogłasza zwycięzcę i rozpoczyna się nowa rozgrywka.
[ ARBITER:: zgłoszenie:(1..4) integer; tura, i: integer; *[(j:1..4) zgłoszenie(j) <> -1 -> zgłoszenie(j) := -1]; *[(j:1..16) GRACZ(j)?tura -> [tura < 5 -> [zgłoszenie(tura) <> -1 -> [(k:1..16) k = zgłoszenie(tura) -> GRACZ(k)!j; GRACZ(j)!k; zgłoszenie(tura) := -1 ] |zgłoszenie(tura) = -1 -> zgłoszenie(tura) := j ] |tura = 5 -> i := 1; *[(k:1..16) k = i -> GRACZ(k)!wygrał(j); i := i + 1] ] ] || GRACZ(i:1..16):: gra: boolean; przeciw, tura, pom, wynik: integer; comment pom i wynik służ± do zapamiętania wylosowanych liczb gra oznacza czy już przegrali¶my w danej rozgrywce *[true -> (tura, gra) := (1, true); *[gra; tura < 5 -> ARBITER!tura; ARBITER?przeciw; pom := losuj(); [i > przeciw -> [(j:1..16) j = przeciw -> GRACZ(j)!pom; GRACZ(j)?wynik; ]; [wynik <= pom -> tura := tura + 1 |wynik > pom -> gra := false ] |i < przeciw -> [(j:1..16) j = przeciw -> GRACZ(j)?wynik; GRACZ(j)!pom; ]; [wynik < pom -> tura := tura + 1 |wynik >= pom -> gra := false ] ] ]; [tura < 5 -> ARBITER?wygrał(pom) |tura = 5 -> ARBITER!tura; ARBITER?wygrał(pom) ] ] ]