Wprowadzenie do programowania współbieżnego Marcin Engel Instytut Informatyki Uniwersytet Warszawski
Zamiast wstępu...
Zamiast wstępu... Możliwość wykonywania wielu akcji jednocześnie może ułatwić tworzenie oprogramowania
Zamiast wstępu... Możliwość wykonywania wielu akcji jednocześnie może ułatwić tworzenie oprogramowania We współczesnych środowiskach można uruchomić wiele aplikacji jednocześnie
Sortowanie przez scalanie procedure MergeSort (i, j: integer); {...} m := (i+j) div 2; MergeSort (i, m); MergeSort (m+1, j); Merge (i, m, j) end;
Współbieżne sortowanie przez scalanie procedure MergeSort (i, j: integer); {...} m := (i+j) div 2; co MergeSort (i, m); MergeSort (m+1, j) coend; Merge (i, m, j) end;
Zamiast wstępu... Możliwość wykonywania wielu akcji jednocześnie może ułatwić tworzenie oprogramowania We współczesnych środowiskach można uruchomić wiele aplikacji jednocześnie
Zamiast wstępu... Możliwość wykonywania wielu akcji jednocześnie może ułatwić tworzenie oprogramowania We współczesnych środowiskach można uruchomić wiele aplikacji jednocześnie Niektóre problemy daj a się łatwo i elegancko wyrazić w postaci niezależnie wykonywanych procedur
Rozpraszanie obliczeń Wyrażenie: A B (C + D)/(E F)
Rozpraszanie obliczeń Wyrażenie: A B (C + D)/(E F) x1 := C + D
Rozpraszanie obliczeń Wyrażenie: A B (C + D)/(E F) x1 := C + D x2 := E F
Rozpraszanie obliczeń Wyrażenie: A B (C + D)/(E F) x1 := C + D x4 := x1/x2 x2 := E F
Rozpraszanie obliczeń Wyrażenie: A B (C + D)/(E F) x1 := C + D x4 := x1/x2 x2 := E F x3 := A B
Rozpraszanie obliczeń Wyrażenie: A B (C + D)/(E F) x1 := C + D x4 := x1/x2 x2 := E F x5 := x3 x4 x3 := A B
Rozpraszanie obliczeń Wyrażenie: A B (C + D)/(E F)
Rozpraszanie obliczeń Wyrażenie: A B (C + D)/(E F) x1 := C + D x2 := E F x3 := A B
Rozpraszanie obliczeń Wyrażenie: A B (C + D)/(E F) x1 := C + D x4 := x1/x2 x2 := E F x3 := A B
Rozpraszanie obliczeń Wyrażenie: A B (C + D)/(E F) x1 := C + D x4 := x1/x2 x2 := E F x5 := x3 x4 x3 := A B
Zamiast wstępu... Możliwość wykonywania wielu akcji jednocześnie może ułatwić tworzenie oprogramowania We współczesnych środowiskach można uruchomić wiele aplikacji jednocześnie Niektóre problemy daj a się łatwo i elegancko wyrazić w postaci niezależnie wykonywanych procedur
Zamiast wstępu... Możliwość wykonywania wielu akcji jednocześnie może ułatwić tworzenie oprogramowania We współczesnych środowiskach można uruchomić wiele aplikacji jednocześnie Niektóre problemy daja się łatwo i elegancko wyrazić w postaci niezależnie wykonywanych procedur Coraz tańsze architektury wieloprocesorowe stwarzaj a możliwość jednoczesnego wykonywania wielu obliczeń
Zamiast wstępu... Możliwość wykonywania wielu akcji jednocześnie może ułatwić tworzenie oprogramowania We współczesnych środowiskach można uruchomić wiele aplikacji jednocześnie Niektóre problemy daja się łatwo i elegancko wyrazić w postaci niezależnie wykonywanych procedur Coraz tańsze architektury wieloprocesorowe stwarzaja możliwość jednoczesnego wykonywania wielu obliczeń Serwery sieciowe obsługuja jednocześnie wielu klientów
Zamiast wstępu... Możliwość wykonywania wielu akcji jednocześnie może ułatwić tworzenie oprogramowania We współczesnych środowiskach można uruchomić wiele aplikacji jednocześnie Niektóre problemy daja się łatwo i elegancko wyrazić w postaci niezależnie wykonywanych procedur Coraz tańsze architektury wieloprocesorowe stwarzaja możliwość jednoczesnego wykonywania wielu obliczeń Serwery sieciowe obsługuja jednocześnie wielu klientów...
Zamiast wstępu... Możliwość wykonywania wielu akcji jednocześnie może ułatwić tworzenie oprogramowania We współczesnych środowiskach można uruchomić wiele aplikacji jednocześnie Niektóre problemy daja się łatwo i elegancko wyrazić w postaci niezależnie wykonywanych procedur Coraz tańsze architektury wieloprocesorowe stwarzaja możliwość jednoczesnego wykonywania wielu obliczeń Serwery sieciowe obsługuja jednocześnie wielu klientów...
Programowanie współbieżne Praca współbieżna polega na tym, że składajace się na nia zjawiska, czynności lub działania odbywaja się równocześnie.
Proces a program Proces to realizacja programu w konkretnym środowisku Proces jest obiektem dynamicznym Program jest obiektem statycznym Proces jest w jednym z następujacych stanów gotowy wykonywany wstrzymany
Programowanie współbieżne Praca współbieżna polega na tym, że składajace się na nia zjawiska, czynności lub działania odbywaja się równocześnie.
Programowanie współbieżne Praca współbieżna polega na tym, że składajace się na nia zjawiska, czynności lub działania odbywaja się równocześnie. Istotny jest przy tym punkt widzenia obserwatora (... )
Współbieżność a równoległość Dwa procesy wykonuja się równolegle, jeśli ich akcje sa wykonywane w tym samym czasie Dwa procesy wykonuja się współbieżnie, jeśli wykonywanie jednego z nich zaczęło się po rozpoczęciu, ale przed zakończeniem drugiego Współbieżność jest abstrakcja równoległości
Co nas interesuje? Notacje i techniki do wyrażania współbieżności Problemy powstajace przy współbieżnym działaniu procesów Metody realizacji poprawnej synchronizacji procesów
Problemy z analiza programów współbieżnych var y: integer process P; var x: integer; i: integer; for i := 1 to 5 do x := y; x := x + 1; y := x end end process P; var x: integer; i: integer; for i := 1 to 5 do x := y; x := x + 1; y := x end end y := 0; co P; P coend; writeln (y)
Niepodzielność instrukcji var y: process P; var i: integer; for i := 1 to 5 do y := y + 1; end; integer process P; var i: integer; for i := 1 to 5 do y := y + 1; end; y := 0; co P; P coend; writeln (y)
Wnioski Kłopoty z testowaniem Nie wolno nic zakładać o niepodzielności instrukcji języka programowania
Współbieżne sortowanie przez scalanie procedure MergeSort (i, j: integer); {...} m := (i+j) div 2; co MergeSort (i, m); MergeSort (m+1, j) Merge (i, m, j) coend; end;
Wniosek Nie wolno nic zakładać o szybkości pracy poszczególnych procesów
Przeplot Przeplot jest ciagiem złożonym z przeplecionych ze soba akcji poszczególnych procesów Nie precyzujemy terminu akcja Konkretne wykonanie programu współbieżnego odpowiada pewnemu przeplotowi Program współbieżny musi dawać poprawne wyniki dla każdego możliwego przeplotu Duży (najczęściej nieskończony) zbiór przeplotów do rozpatrzenia
Klasyczne problemy współbieżności Wzajemne wykluczanie
Klasyczne problemy współbieżności Wzajemne wykluczanie Producenci i konsumenci
Klasyczne problemy współbieżności Wzajemne wykluczanie Producenci i konsumenci Czytelnicy i pisarze
Klasyczne problemy współbieżności Wzajemne wykluczanie Producenci i konsumenci Czytelnicy i pisarze Pięciu filozofów
Wzajemne wykluczanie Mamy dwa procesy działajace według schematu: while true do własne sprawy;... sekcja krytyczna;... end; Uzupełnić tekst procesu tak, aby w tym samym czasie sekcję krytyczna wykonywał co najwyżej jeden proces.
Wzajemne wykluczanie założenia Własne sprawy jest fragmentem programu, który nie wymaga synchronizacji nic poza tym o nim nie wiadomo Sekcja krytyczna jest krótka; każdy proces, który rozpocznie jej wykonanie w skończonym czasie je kończy Proces, który nie może od razu wejść do sekcji krytycznej musi poczekać i wejść do niej, gdy będzie to możliwe
Wzajemne wykluczanie założenia Własne sprawy jest fragmentem programu, który nie wymaga synchronizacji nic poza tym o nim nie wiadomo Sekcja krytyczna jest krótka; każdy proces, który rozpocznie jej wykonanie w skończonym czasie je kończy Proces, który nie może od razu wejść do sekcji krytycznej musi poczekać i wejść do niej, gdy będzie to możliwe Sprawiedliwość Każdy gotowy do wykonania proces w skończonym czasie stanie się wykonywany.
Poprawność programów współbieżnych bezpieczeństwo Własność zapewniania (lub bezpieczeństwa): nigdy nie dojdzie do sytuacji niepożadanej Własność zapewniania pojawia się w specyfikacji problemu synchronizacyjnego Odpowiednik częściowej poprawności programu sekwencyjnego
Poprawność programów współbieżnych bezpieczeństwo Własność zapewniania (lub bezpieczeństwa): nigdy nie dojdzie do sytuacji niepożadanej Własność zapewniania pojawia się w specyfikacji problemu synchronizacyjnego Odpowiednik częściowej poprawności programu sekwencyjnego Bezpieczeństwo wzajemnego wykluczania W sekcji krytycznej nigdy nie przebywaj a oba procesy jednocześnie.
Dwa modele współbieżności Model scentralizowany: procesy wykonuja się w środowisku ze wspólna pamięcia, w której w szczególności można umieścić zmienne globalne (współdzielone) Model rozproszony: synchronizacja odbywa się poprzez wymianę komunikatów
System operacyjny Unix/Linux Z logicznego punktu widzenia domyślnie wspiera model rozproszony Procesy maja odrębne wirtualne przestrzenie adresowe Mechanizmy takie jak łacza, łacza nazwane, kolejki komunikatów stanowia narzędzia synchronizacyjne Fizycznie, procesy działajace na tym samym komputerze korzystaja ze wspólnej pamięci Segmenty pamięci dzielonej oraz semafory wspieraj a model scentralizowany
Wzajemne wykluczanie w modelu scentralizowanym Bez wsparcia ze strony sprzętu ani środowiska Za pomoca specjalnego, niepodzielnego rozkazu maszynowego Za pomoc a mechanizmów wspieranych przez system operacyjny i sprzęt, np. semaforów
Rozwiazanie oczywiste var zajęte : boolean := false; process P1; while true do własne sprawy; while zajęte do; zajęte := true; sekcja krytyczna; zajęte := false end end; process P2; while true do własne sprawy; while zajęte do; zajęte := true; sekcja krytyczna; zajęte := false end end;
Rozwiazanie oczywiste var zajęte : boolean := false; process P1; while true do własne sprawy; while zajęte do; zajęte := true; sekcja krytyczna; zajęte := false end end; Dwa procesy w sekcji krytycznej! process P2; while true do własne sprawy; while zajęte do; zajęte := true; sekcja krytyczna; zajęte := false end end;
Rozwiazanie poprawne var zajęte : boolean := false; process P1; while true do własne sprawy; zajęte := true; while zajęte do; sekcja krytyczna; zajęte := false end end; process P2; while true do własne sprawy; zajęte := true; while zajęte do; sekcja krytyczna; zajęte := false end end;
Rozwiazanie poprawne var zajęte : boolean := false; process P1; while true do własne sprawy; zajęte := true; while zajęte do; sekcja krytyczna; zajęte := false end end; Teraz jest bezpiecznie! process P2; while true do własne sprawy; zajęte := true; while zajęte do; sekcja krytyczna; zajęte := false end end;
Rozwiazanie poprawne? var zajęte : boolean := false; process P1; while true do własne sprawy; zajęte := true; while zajęte do; sekcja krytyczna; zajęte := false end end; process P2; while true do własne sprawy; zajęte := true; while zajęte do; sekcja krytyczna; zajęte := false end end; Teraz jest bezpiecznie! Ale czy na pewno o to chodziło?
Poprawność programów współbieżnych żywotność Własność żywotności: każdy proces, który chce wykonać pewna akcję w skończonym czasie będzie mógł to zrobić Własność żywotności jest zwiazana z wykonaniem programu Odpowiednik całkowitej poprawności programu sekwencyjnego (razem z własnościa bezpieczeństwa)
Poprawność programów współbieżnych żywotność Własność żywotności: każdy proces, który chce wykonać pewna akcję w skończonym czasie będzie mógł to zrobić Własność żywotności jest zwiazana z wykonaniem programu Odpowiednik całkowitej poprawności programu sekwencyjnego (razem z własnościa bezpieczeństwa) Przejawy braku żywotności Zakleszczenie, np. reguła prawej ręki w ruchu drogowym Zagłodzenie, np. klienci banku obsługiwani poza kolejnościa
Poprawność wzajemnego wykluczania bezpieczeństwo + żywotność
Poprawność wzajemnego wykluczania bezpieczeństwo + żywotność W sekcji krytycznej przebywa w tym samym czasie co najwyżej jeden proces
Poprawność wzajemnego wykluczania bezpieczeństwo + żywotność W sekcji krytycznej przebywa w tym samym czasie co najwyżej jeden proces Każdy proces, który chce wejść do sekcji krytycznej, w końcu do niej wejdzie
Poprawność wzajemnego wykluczania bezpieczeństwo + żywotność W sekcji krytycznej przebywa w tym samym czasie co najwyżej jeden proces Każdy proces, który chce wejść do sekcji krytycznej, w końcu do niej wejdzie Poprzednie rozwi azanie jest niepoprawne (prowadzi do zakleszczenia).
Rozwiazanie poprawne? var chce1, chce2 : boolean := false; process P1; while true do własne sprawy; chce1 := true; while chce2 do; sekcja krytyczna; chce1 := false end end; process P2; while true do własne sprawy; chce2 := true; while chce1 do; sekcja krytyczna; chce2 := false end end;
Rozwiazanie znów niepoprawne var chce1, chce2 : boolean := false; process P1; while true do własne sprawy; chce1 := true; while chce2 do; sekcja krytyczna; chce1 := false end end; process P2; while true do własne sprawy; chce2 := true; while chce1 do; sekcja krytyczna; chce2 := false end end; Lecz w tym cały jest ambaras, kiedy dwoje chce... naraz.
Rozwiazanie poprawne? var kto_czeka : integer := 1; process P1; while true do własne sprawy; while kto_czeka=1 do; sekcja krytyczna; kto_czeka := 1 end end; process P2; while true do własne sprawy; while kto_czeka = 2 do; sekcja krytyczna; kto_czeka := 2 end end;
Rozwiazanie znów niepoprawne var kto_czeka : integer := 1; process P1; while true do własne sprawy; while kto_czeka=1 do; sekcja krytyczna; kto_czeka := 1 end end; process P2; while true do własne sprawy; while kto_czeka = 2 do; sekcja krytyczna; kto_czeka := 2 end end; Lecz w tym cały jest ambaras, żeby dwoje chciało naraz.
Rozwiazanie prawie poprawne? var kto_czeka : integer := 1; chce1, chce2: boolean := false process P1; while true do własne sprawy; chce1 := true; while chce2 and (kto_czeka=1) do; sekcja krytyczna; chce1 := false; kto_czeka := 1 end end; process P2; while true do własne sprawy; chce2 := true; while chce1 and (kto_czeka = 2) do; sekcja krytyczna; chce2 := false; kto_czeka := 2 end end;
Wreszcie dobrze! var kto_czeka : integer := 1; chce1, chce2: boolean := false process P1; while true do własne sprawy; chce1 := true; kto_czeka := 1 while chce2 and (kto_czeka=1) do; sekcja krytyczna; chce1 := false; end end; process P2; while true do własne sprawy; chce2 := true; kto_czeka := 2 while chce1 and (kto_czeka = 2) do; sekcja krytyczna; chce2 := false; end end;
Algorytm Petersona Aktywne oczekiwanie Jedynie dla dwóch procesów, choć daje się uogólnić na większa ich liczbę Duży koszt Niestosowany w praktyce
Wsparcie ze strony sprzętu Niepodzielny rozkaz maszynowy Test_and_Set(G) Jednoczesny zapis i odczyt, np.: Test_and_Set (Li) Li := G; G := 1; end;
Rozwiazanie problemu wzajemnego wykluczania var G: integer := 0; process P; var Li: integer; while true do sekcja_lokalna(i); loop Test_and_Set(Li); exit when Li = 0; end loop sekcja_krytyczna(i); G := 0; end end;
Semafory Niepodzielne i atomowe operacje podniesienia (V)i opuszczenia (P) semafora Proces próbujacy opuścić semafor zamknięty jest wstrzymywany Proces podnoszacy semafor budzi proces oczekujacy przed semaforem
Rozwi azanie problemu wzajemnego wykluczania process P; while true do własne sprawy; P(S); sekcja krytyczna; V (S); end end;