15. MECHANIZMY SYNCHRONIZACJI WĄTKÓW Większość koncepcji stworzonych na potrzeby synchronizacji procesów ciężkich została zastosowana też do synchronizacji.

Slides:



Advertisements
Podobne prezentacje
Zerowanie mikroprocesorów Cel: wprowadzenie mikroprocesora w określony stan początkowy Zwykle realizowany poprzez: inicjalizację licznika rozkazów (PC)
Advertisements

C++ wykład 4 ( ) Przeciążanie operatorów.
Język C/C++ Funkcje.
Mechanizmy pracy równoległej
Modelowanie aktywności
Jarosław Kuchta Monitory.
Diagramy stanów i diagramy aktywności
Wzorce.
Systemy rozproszone W. Bartkiewicz
PROGRAMOWANIE STRUKTURALNE
Zaawansowana obsługa sygnałów
Sygnały Cz. 3 EAIiE Katedra Automatyki Kraków,
Sygnały Proponowane rozwiązanie EAIiE Katedra Automatyki Kraków,
Internet Communication Engine
Podstawowe składniki funkcjonalne procesora i ich rola.
Struktury.
Tablice.
Systemy operacyjne Wykład nr 5: Wątki Piotr Bilski.
Systemy operacyjne Wykład nr 4: Procesy Piotr Bilski.
Wykład nr 2: Struktura systemu komputerowego a system operacyjny
Mechanika dzielenia na podsieci. Wykład 6
Temat nr 10: System przerwań
SO – LAB3 Wojciech Pieprzyca
Projektowanie i programowanie obiektowe II - Wykład IV
Język Java Wielowątkowość.
12. GNIAZDA BSD Biblioteka funkcji związanych z gniazdami jest interfejsem programisty do obsługi protokołów komunikacyjnych. Została utworzona dla Unixa.
Muteksy Muteksy (mutex – MUTual EXclusion) są prostymi obiektami synchronizacyjnymi pełniącymi rolę semaforów binarnych dla wątków (chroniącymi sekcje.
Semafory według normy POSIX
14. WĄTKI Procesy w tradycyjnym sensie (tworzone przez wykonanie funkcji fork) mają przydzielaną oddzielną przestrzeń adresową. W przestrzeni tej jest.
10. PROSTE MECHANIZMY KOORDYNACJI DOSTĘPNE W JĘZYKU C W systemie Unix użytkownikowi (nie będącemu administratorem) nie wolno wykonywać bezpośrednio żadnych.
9. KOORDYNACJA PROCESÓW WSPÓŁBIEŻNYCH PRZY UŻYCIU INTERPRETATORA
1 Podstawy informatyki H. P. Janecki- 2006_ Systemy Operacyjne W6.
Procesy odrębne –Unikatowy PID ( ) –Zmienne –Zbiory deskryptorów plików –Przestrzeń stosu (lokalne zmienne, wywołania funkcji) –Środowisko –Licznik.
Wątki.
Pamięć wspólna Opis własnego rozwiązania Marcin Kamiński, Michał Kotra Wydział EAIiE Katedra Automatyki Kraków, 2008.
Pamięć wspólna Przegląd stosowanych rozwiązań Marcin Kamiński, Michał Kotra Wydział EAIiE Katedra Automatyki Kraków, 2008.
Pakiety w Javie Łukasz Smyczyński (132834). Czym są pakiety? Klasy w Javie są grupowane w pewne zbiory zwane pakietami. Pakiety są więc pewnym podzbiorem.
Podstawy programowania II
PROGRAMOWANIE SYSTEMOWE [2/3]
Linux - polecenia.
Automatyka i Robotyka Systemy czasu rzeczywistego Wykład 4.
Prezentacja i szkolenie
Jerzy F. Kotowski1 Informatyka I Wykład 14 DEKLARATORY.
JAVA c.d.. Instrukcji wyboru SWITCH używamy, jeśli chcemy w zależności od wartości pewnego wyrażenia wykonać jeden z kilku fragmentów kodu. Jest to w.
Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/21 Dariusz Wardowski.
Programowanie obiektowe Wykład 6 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/14 Dariusz Wardowski.
Problem sekcji krytycznej
Przerwanie ang. interrupt.
Buforowanie D e f i n i c j a.
Koncepcja procesu Zadanie i proces. Definicja procesu Process – to program w trakcie wykonywania; wykonanie procesu musi przebiegać w sposób sekwencyjny.
Przekazywanie parametrów do funkcji oraz zmienne globalne i lokalne
Programowanie obiektowe – język C++
Programowanie obiektowe 2013/2014
W ą t e k (lekki proces) thread.
SYSTEMY OPERACYJNE I SIECI KOMPUTEROWE
Bariery synchronizacyjne Bariery są obiektami synchronizacyjnymi pakietu pthread służącymi do wyrównywania czasów pracy wątków wykonujących wspólne zadanie.
Programowanie strukturalne i obiektowe C++
Procesy, wątki Program a proces Proces: Przestrzeń adresowa, kod, dane, stos (część pamięci do przechowania zmiennych lokalnych i niektórych adresów) Otwarte.
Projektowanie obiektowe. Przykład: Punktem wyjścia w obiektowym tworzeniu systemu informacyjnego jest zawsze pewien model biznesowy. Przykład: Diagram.
Paweł Starzyk Obiektowe metody projektowania systemów
Struktura systemu operacyjnego
Tryby adresowania i formaty rozkazów mikroprocesora
Podział sieci IP na podsieci w ramach CISCO
K URS JĘZYKA C++ – WYKŁAD 3 ( ) Przenoszenie Składowe statyczne Funkcje wbudowane Argumenty domyślne.
Testy jednostkowe. „Test jednostkowy (unit test) to fragment kodu, który sprawdza inny fragment kodu”
Typy wyliczeniowe, kolekcje
Wątki, programowanie współbieżne
Klasy, pola, obiekty, metody. Modyfikatory dostępu, hermetyzacja
Programowanie Obiektowe – Wykład 2
Zapis prezentacji:

15. MECHANIZMY SYNCHRONIZACJI WĄTKÓW Większość koncepcji stworzonych na potrzeby synchronizacji procesów ciężkich została zastosowana też do synchronizacji wątków, ale z pewnymi zmianami. Intencją implementatorów było, aby biblioteka funkcji obsługujących wątki (w przypadku Linuksa biblioteka pthread) była oddzielnym, samowystarczalnym narzędziem. Zalecana jest duża ostrożność w przypadku używania w jednym programie zarówno funkcji mogących blokować procesy, jak i funkcji mogących blokować wątki (skutki mogą być nieokreślone). W systemach Linux można spotkać dwie realizacje biblioteki pthread: - LinuxThreads (starsza, obecnie już nie wspierana); - NPTL (Native POSIX Thread Library) – oparta na własnościach jądra systemu od 2.6 w górę. Norma POSIX w odniesieniu do wątków w dużym stopniu wzoruje się na realizacji biblioteki threads w systemach Solaris firmy Sun.

Obecna realizacja NPTL jest jeszcze dość odległa od zaimplementowania w całości standardu POSIX (nie są dostępne jeszcze wszystkie przewidziane obiekty synchronizacji wątków). Realizacja funkcji synchronizujących wątki oparta jest na funkcji systemowej futex( ) (która nie jest jeszcze przenośna na wszystkie platformy sprzętowe, na których działa Linux). Wybrane źródła informacji: man pthreads (w systemach linuksowych); (opisy wszystkich funkcji przewidzianych przez POSIX). Wśród mechanizmów synchronizacji wątków zrealizowanych w systemach Linux należy wymienić: - wcielenie (join); - unieważnienie (cancel); - muteksy (mutex); - zmienne warunkowe (condition variable); - obsługę sygnałów (signal) przez wątki; - semafory (semaphore) POSIX.

Przy okazji omawiania zagadnień synchronizacji wątków na ogół omawiane są również tak zwane dane specyficzne wątków (thread specific data, TSD), które nie są mechanizmem synchronizacji, i które stanowią, w pewnym sensie, przeciwieństwo pojęcia pamięci dzielonej dla procesów. Wśród mechanizmów nie zrealizowanych jeszcze w Linuksach (a zrealizowanych w systemach Solaris) należy wymienić: - blokady zapisu/odczytu (read/write lock, RW lock); - blokady wirujące (spin lock); - bariery (barrier). Większość spośród wyżej wymienionych mechanizmów synchronizacji realizowanych jest przez obiekty synchronizacyjne, które, zgodnie z normą POSIX, powinny być tworzone i usuwane dynamicznie w programie, i których początkowy stan powinien być określony przez wskazanie na pewien obiekt atrybutów (podobnie, jak w przypadku samych wątków). Zgodnie z normą POSIX powinno być możliwe umieszczanie obiektów synchronizacyjnych w segmentach pamięci wspólnej (w celu synchronizacji wątków niespokrewnionych).

Unieważnienie Unieważnienie polega na wysłaniu jednemu wątkowi przez drugi żądania zakończenia działania (czyli przeskoku do funkcji pthread_exit( )). Żądanie takie formalnie nie jest zaliczane do sygnałów, choć ma podobny charakter (i podobną wewnętrzną realizację) – wątek otrzymuje je asynchronicznie (czyli w nieprzewidzianym przez siebie momencie). Ze względu na sposób reagowania na takie żądania każdemu wątkowi przypisany jest stan oraz typ, które można zmieniać odpowiednimi funkcjami. Są dwa stany: 1) ignorowania żądań (PTHREAD_CANCEL_DISABLE); 2) przyjmowania żądań (PTHREAD_CANCEL_ENABLE). Jeśli wątek jest w stanie przyjmowania żądań, to typ reakcji może być: 1) natychmiastowy (PTHREAD_CANCEL_ASYNCHRONOUS); 2) opóźniony (PTHREAD_CANCEL_DEFERRED).

Jeśli typ reakcji został ustalony jako opóźniony, to wątek wywołuje funkcję pthread_exit( ) dopiero po dotarciu do najbliższego (chronologicznie) punktu unieważnienia (cancellation point) w swoim programie. Standard POSIX podaje wykaz funkcji (można go znaleźć na przykład w man pthreads), których miejsca wywołań w programie powinny być uważane za punkty unieważnienia. Zazwyczaj są to funkcje mogące blokować wątki, na przykład pthread_join( ), pthread_cond_wait( ), pthread_cond_timedwait( ), sem_wait( ), sigwait( ), ale może też to być nieblokująca funkcja pthread_testcancel( ), jak również funkcje mogące blokować procesy, takie jak read( ) czy write( ). W powyższym zakresie standard POSIX prawdopodobnie jeszcze nigdzie nie został zaimplementowany w całości. Poza wspomnianym wyżej wykazem, POSIX zaleca, aby w przyszłych implementacjach wszystkie funkcje potencjalnie blokujące były traktowane jako punkty unieważnienia.

int pthread_cancel (pthread_t id); Zwraca: 0 w przypadku sukcesu niezerowy kod w przypadku błędu id – identyfikator wątku Działanie: wysyła żądanie zakończenia do wątku o identyfikatorze id. int pthread_setcancelstate (int stan, int *poprzedni_stan); Zwraca: 0 w przypadku sukcesu niezerowy kod w przypadku błędu stan – nowy stan, jaki ma być przyjęty przez wywołujący wątek poprzedni_stan – jeśli nie jest NULL, to pod tym adresem będzie pamiętany dotychczasowy stan

Działanie: ustala nowy stan wątku, który wywołał tę funkcję (i ewentualnie zapamiętuje dotychczasowy stan). int pthread_setcanceltype (int typ, int *poprzedni_typ); Zwraca: 0 w przypadku sukcesu niezerowy kod w przypadku błędu typ – nowy typ reakcji na żądanie zakończenia działania poprzedni_typ – jeśli nie jest NULL, to pod tym adresem będzie pamiętany dotychczasowy typ Działanie: ustala nowy typ reakcji wątku, który wywołał tę funkcję (i ewentualnie zapamiętuje dotychczasowy typ). void pthread_testcancel (void); Działanie: ustanawia punkt unieważnienia (i nic więcej).

Sygnały wątkowe Z powodu wprowadzenia wielowątkowości działanie sygnałów w systemach uniksowych znacznie skomplikowało się. Jednym ze skutków jest to, że obecnie w programach wielowątkowych nie jest zalecane używanie tradycyjnej funkcji signal ( ) (jej działanie może dać skutki nieokreślone) – zamiast niej zalecana jest (zgodna z normą POSIX) funkcja sigaction( ). W celu implementacji odwzorowania wykonywanych wątków na procesy lekkie jądra systemu wprowadzono kilka dodatkowych sygnałów (o numerach powyżej 30) – ich bezpośrednie użycie w programach jest niezalecane. W przypadku procesów zawierających wiele wątków można rozpatrywać następujące sytuacje: - wątek sam spowodował konieczność wysłania sygnału przez jądro systemu (na przykład wskutek próby dzielenia przez 0) – w takim przypadku ten właśnie wątek będzie odbiorcą sygnału; - wątek wysłał sygnał do wątku spokrewnionego wywołując funkcję pthread_kill ( ) – w takim przypadku sygnał otrzyma jego adresat; - do procesu dotarł sygnał asynchroniczny z zewnątrz.

W tej ostatniej sytuacji może mieć miejsce: a) zatrzymanie całego procesu (szczególnie w przypadku sygnału nieprzechwytywalnego SIGKILL); b) obsługa sygnału przez jeden z wątków procesu (jeśli maski sygnałów umożliwiają to kilku wątkom, wybór jednego z nich będzie niedeterministyczny). int pthread_sigmask (int sposób, const sigset_t *nowa_maska, sigset_t *poprzednia_maska); Zwraca: 0 w przypadku sukcesu; niezerowy kod w przypadku błędu sposób – SIG_SETMASK, SIG_BLOCK lub SIG_UNBLOCK nowa_maska – wskaźnik na wykaz sygnałów poprzednia_maska - jeśli nie jest NULL, to pod tym adresem będzie pamiętana dotychczasowa maska Działanie: jeśli sposób jest równy SIG_SETMASK, to ustawia maskę sygnałów wywołującego wątku dokładnie na podaną, jeśli SIG_BLOCK, to nowe sygnały są dokładane do dotychczasowych, a jeśli SIG_UNBLOCK, to usuwane spośród dotychczasowych.

int pthread_kill (pthread_t id, int sygnał); Zwraca: 0 w przypadku sukcesu niozerowy kod w przypadku błędu id – identyfikator wątku, do którego wysyłany jest sygnał sygnał – identyfikator rodzaju sygnału Działanie: wysyła dany sygnał do danego wątku. int sigwait (const sigset_t *zbiór, int *sygnał); Zwraca: zawsze 0 zbiór – wskaźnik na zbiór sygnałów, na jakie wątek ma czekać sygnał – jeśli nie jest NULL, to pod tym adresem będzie zapamiętany sygnał, który przyjdzie jako pierwszy z podanego zbioru

Działanie: wywołujący wątek zostaje zawieszony aż do nadejścia dowolnego z sygnałów z podanego zbioru – wtedy identyfikator tego sygnału zostaje zapamiętany pod adresem podanym przez drugi argument funkcji. Sygnał musi być uwzględniony w masce sygnałów danego wątku (nie może być zablokowany). Jeśli z sygnałem związana jest jakaś funkcja jego obsługi (zarejestrowana dla całego procesu), nie jest ona wykonywana. Uwaga: Funkcje obsługi sygnałów przychodzących z zewnątrz procesu są zarejestrowane dla całego procesu (wszystkie wątki procesu je wspóldzielą), ale są wykonywane (w razie potrzeby) przez pojedynczy wątek. Wątki posiadają swoje indywidualne maski sygnałów. Wątek, który ma wykonać funkcję obsługi przybyłego sygnału, za każdym razem jest niedeterministycznie wybierany spośród tych wątków, które w danej chwili mają ten sygnał uwzględniony w swojej masce.