Programowanie współbieżne Wykład 7 Iwona Kochaoska
Poprawnośd programów współbieżnych Właściwości związane z poprawnością programu współbieżnego: Właściwośd żywotności - program współbieżny jest żywotny, jeśli zapewnia, że każde pożądane zdarzenie w koocu zajdzie. Żywotnośd w wyniku przetwarzania, po skooczonej liczbie zdarzeo, zajdzie określony (oczekiwany) warunek. Żywotnośd może byd naruszona poprzez: deadlock zagłodzenie procesu/wątku livelock
Deadlock - zakleszczenie deadlock - zakleszczenie, blokada wzajemna. Sytuacja, w której co najmniej dwie różne akcje czekają na siebie nawzajem, więc żadna nie może się zakooczyd https://pl.wikipedia.org/wiki/plik:deadlock_diagram_pl.svg
Deadlock - zakleszczenie https://austingwalters.com/multithreading-common-pitfalls/ Każdy z wątków: A i B potrzebuje dostępu do wszystkich 4 zasobów, aby zakooczyd swoje działanie.
Deadlock - zakleszczenie Prawidłowa kolejnośd alokowania zasobów https://pl.wikipedia.org/wiki/plik:no_deadlock.svg
Livelock livelock - podobny do deadlock, przy czym stan dwóch procesów związanych z blokadą zmienia się w stosunku do drugiego procesu. Przykład z życia : dwoje ludzi spotyka się w wąskim korytarzu i każdy chce byd uprzejmy. Odsuwają się na bok w obie strony, by przepuścid drugą osobę, ale ponieważ obydwaj poruszają się w ten sam sposób, nie mogą się minąd. deadlock powoduje nieskooczone oczekiwanie, podczas gdy livelock powoduje marnowanie cykli procesora.
Livelock https://austingwalters.com/multithreading-common-pitfalls/
Livelock https://www.logicbig.com/tutorials/core-java-tutorial/java-multi-threading/thread-livelock.html
Zagłodzenie - starvation Zagłodzenie sytuacja, gdy procesowi nieustannie odmawia się niezbędnych zasobów. Bez tych zasobów program nigdy nie może zakooczyd swojego zadania. Występuje wtedy, gdy dwa programy posiadają zasoby, które musi ukooczyd drugi i żaden nie jest skłonny ich oddad. Występuje najczęściej na skutek: niewłaściwej pracy algorytmu szeregowania, którego zadaniem jest sprawiedliwy przydział zasobów, nadmiernego obciążenia systemu.
Zagłodzenie - starvation https://austingwalters.com/multithreading-common-pitfalls/
Poprawnośd programów współbieżnych Właściwości związane z poprawnością programu współbieżnego: Właściwośd bezpieczeostwa - program współbieżny jest bezpieczny, jeśli nigdy nie doprowadza do niepożądanego stanu. Bezpieczeostwo w każdym stanie przetwarzania współbieżnego (niezależnie od przeplotu) spełniony będzie pewien warunek, zwany od nazwy własności warunkiem bezpieczeostwa,
Bezpieczeostwo Bezpieczeostwo = thread-safety Segment kodu jest thread-safe jeśli manipuluje współdzielonym stanem w taki sposób, że gwarantowane jest bezpieczne (prawidłowe) wykonanie go przez wiele wątków pracujących w tym samym czasie. Kod thread-safe musi w odpowiedni sposób chronid współdzielony między wątkami stan programu. Kod unsafe to kod, który: nieprawidłowo chroni współdzielone dane oraz zasoby (shared state) zależy od zmiennego między wywołaniami stanu (np. funkcja rand()) wywołuje kod, który jest unsafe
Bezpieczeostwo Sposoby osiągnięcia bezpieczeostwa wielowątkowego: Stosowanie jawnego blokowana - muteksów, do ochrony danych współdzielonych. Operacje synchronizacji mogą znacznie spowolnid działanie programu. Niezmiennośd danych (Immutability) - stan obiektu nie może byd zmieniony po jego utworzeniu. Obiekty mogą byd bezpiecznie współdzielone, jeśli wątki mogą jedynie odczytywad ich stan. Atomowośd (Atomicity) - stosowanie zmiennych i flag atomowych
Wyścig (race condition, hazard) Wyścig (ang. race conditions) sytuacja, w której dwa lub więcej procesów wykonuje operację na zasobach dzielonych, a ostateczny wynik tej operacji jest zależny od momentu jej realizacji Aby zapobiec warunkom wyścigu należy stworzyd mechanizm zabraniający więcej niż jednemu procesowi dostępu do zasobów dzielonych w tym samym czasie. Należy wprowadzid mechanizm wzajemnego wykluczania (mutual exclusion) W poprawnym programie nie powinno byd wyścigów!
Pierwszy wyścig w historii (systemów komputerowych) o tragicznych skutkach
Wyścig Wątek A i wątek B zwiększają wartośd licznika w tym samym czasie, jednak po zakooczeniu ich działania licznik zwiększył się o 1, nie o 2!
Wyścig (race condition)
Wyścig (race condition) Fragment kodu źródłowego: int a = 1; //instrukcja 1 a = a * 5; //instrukcja 2 int b = a 1; //instrukcja 3 Wartość zmiennej b w zależności od kolejności wykonania instrukcji Kolejność Wartość zmiennej b 1,2,3 4 1,3,2 0 każda inna nieokreślona
kiedy kompilator może dokonywad operacji wyłącznie na rejestrach, a kiedy musi dokonad zapisu do pamięci Wyścig (race condition) jak utrzymad spójnośd kopii danych w pamięci podręcznej z wartością w pamięci głównej czy kompilator i procesor mogą zmieniad kolejnośd wykonywanych operacji (w tym operacji zapisu i odczytu)
Wyścig (race condition) W obliczeniach sekwencyjnych zagadnienie synchronizacji operacji na kopiach wartości zmiennych jest problemem głównie wydajności kompilatory i procesory są zobowiązane działad tak, aby efekt działania systemu komputerowego był zgodny z za pisem w kodzie źródłowym (czyli złudzeniem istnienia tylko j ednej kopii danych) nie dotyczy to działania debugerów, które śledzą nie ostateczne efekty działania kodu, ale stan systemu po każdej linii kodu
Wyścig (race condition) W obliczeniach równoległych zagadnienie synchronizacji operacji na kopiach wartości zmiennych wpływa na poprawnośd programów: brak wymuszenia operacji zapisu może powodowad, że różne wątki widzą różne wartości tej samej zmiennej wspólnej rozmaite środowiska wprowadzają dodatkowe konstrukcje (memory fences, operacje flush) wymuszające zapis do pamięci niejawne wymuszenie zapisu jest także związane z szeregiem operacji synchronizacji
Literatura http://smurf.mimuw.edu.pl/book/export/html/941 https://austingwalters.com/multithreading-common-pitfalls/ http://www.ia.pw.edu.pl/~tkruk/edu/soib2012/wyklad/w04 http://www.metal.agh.edu.pl/~banas/pr/pr_w02_wspolbiezno sc.pdf