Pobierz prezentację
Pobieranie prezentacji. Proszę czekać
OpublikowałPrzemysław Grodziński Został zmieniony 11 lat temu
1
WĄTKI I ICH SYNCHRONIZACJA Natalia Wyczislok
2
Proces Procesem określamy zazwyczaj wykonywany program w skład, którego wchodzą: kod programu, licznik rozkazów, stos procesu i sekcja danych. System operacyjny jest odpowiedzialny za tworzenie, usuwanie, wstrzymywanie i wznawianie procesów.
3
Wątek Jest to współbieżnie wykonujący się fragment kodu danego procesu Wątek dzieli wraz z innymi równorzędnymi wątkami kod programu, sekcję danych oraz zasoby systemowe. Natomiast wątek posiada własny licznik rozkazów, zbiór rejestrów procesora i stos.
4
Dodatkowo wątek główny może tworzyć nowe wątki, a te z kolei następne. W ten sposób tworzy się hierarchia wątków. Każdy z procesów składa się przynajmniej z jednego wątku głównego którym jest funkcja main. Hierarchia Wątków
5
Zalety Wątków możliwość łatwego dostępu do wspólnych danych programu. Komunikacja miedzy wątkami nie musi odbywać się jak w przypadku procesów za pomocą kosztownych mechanizmów przełączanie procesora między wątkami jest łatwiejsze niż między procesami
6
Wady Wątków jeden błędnie działający wątek może zagrozić działaniu całego procesu. wymagają synchronizacji, które zwiększają rozmiaru programu, a także powodują dodatkowe problemy na etapie tworzenia i testowania programu
7
Tworzenie Wątku HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ); Jeżeli utworzenie nowego wątku przebiegło pomyślnie funkcja zwraca uchwyt wątku. W przypadku błędu zwrócona zostaje wartość NULL.
8
lpThreadAttributes wskaźnik na strukturę SECURITY_ATTRIBUTES określającej atrybuty zabezpieczeń i dostępu do nowego wątku. Wpisanie null spowoduje przyjęcie ustawień domyślnych dwStackSize początkowa (lub zalecana) wielkość stosu nowego wątku, podanie wartości 0 spowoduje przyjęcie przez system domyślnej wielkości stosu; w razie potrzeby wielkość stosu jest automatycznie powiększana przez system. Tworzenie Wątku
9
lpStartAddress – wskaźnik na funkcję wątku, lpParameter – wskaźnik na parametr przekazywany w funkcji wątku, dwCreationFlags – znacznik kontrolujący proces tworzenia wątku; wartość 0 spowoduje natychmiastowe uruchomienie funkcji wątku; aga CREATE _ SUSPENDED spowoduje zawieszenie wykonywania wątku do czasu wywołania funkcji ResumeTheread; Tworzenie Wątku
10
lpThreadId – wskaźnik na zmienną zawierającą unikatowy identykator wątku lpParameter – parametr przekazywany do funkcji wątku Tworzenie Wątku DWORD WINAPI ThreadProc (LPVOID lpParameter)
11
Kończenie Wątku Funkcja TerminateThread zakonczy watek w dowolnym momencie, pamiec może nie zostac zwolniona ExitThread – funkcja zalecana do konczenia wątku, parametr okresla wartosc zwrocona przez funkcje wątku Zakonczenie funkcji wątku czyli niejawne wywolanie funkcji ExitThread
12
Sprzątanie po obiektach Zwalnianie zasobów po wątkach oraz obiektach synchronizacji odbywa się za pomocą funkcji CloseHandle();
13
Usypianie i przełączanie wątków VOID Sleep( DWORD dwMilliseconds) - wątek dobrowolnie oddaje resztę przydzielonego mu czasu cpu, nie jest wykonywany przez czas podany w argumencie. BOOL SwitchToThread() – jeżeli istnieje wątek czekajacy na cpu to natychmiast zostaje mu przekazany kwant czasu.
14
Kontekst wątku Struktura CONTEXT pozwala systemowi pamiętać stan wątku (wartości rejestrów CPU) i podjąć jego wykonywanie w momencie, gdy znów uzyska on dostęp do CPU Składowe struktury CONTEXT zależą od architektury procesora
15
Sekcje struktury Context CONTEXT_CONTROL - obejmuje rejestry kontrolne CPU, takie jak wskaźnik instrukcji,wskaźnik stosu, flagi i adres powrotny funkcji. CONTEXT_INTEGER - obejmuje rejestry całkowite CPU, czyli np. Eax, Ebx, Ecx, Edi, itp. CONEXT_FLOATING_POINT - obejmuje rejestry zmiennoprzecinkowe. CONTEXT_SEGMENTS - obejmuje rejestry segmentowe (tylko x86). CONTEXT_DEBUG_REGISTERS - obejmuje rejestry debugowania (tylko x86). CONTEXT_EXTENDED_REGISTERS - rejestry rozszerzone (tylko x86).
16
Rejestry wątku Aby dobrać się do wartości odpowiednich rejestrów musimy na początku wrzucić do zmiennej DWORD ContextFlags wartość odpowiedniej sekcji (flage) Przed operacjami nad wartościami rejestru trzeba pamiętać o zatrzymaniu wątku funkcją: SuspendThread(hThread); a po zakonczeniu wznowić ResumeThread(hThread);
17
Rejestry wątku GetThreadContext(HANDLE hThread, LPCONTEXT lpContext ); Odczyt: Modyfikacja SetThreadContext( HANDLE hThread, LPCONTEXT pContext)
18
Priorytety wątku Priorytety są złożeniem klasy priorytetu procesu oraz względnych priorytetów wątku. Wartość priorytetu to liczba od 0-31 Planista systemu przydziela czas CPU wątkowi o największym priorytecie.
19
Klasy priorytetu procesu Czasu rzeczywistego - wątki muszą natychmiast reagować na zdarzenia. Wywłaszczają one nawet składowe systemu operacyjnego Wysoki - wątki procesu muszą natychmiast reagować na zdarzenia. Do tej klasy zalicza się Eksplorator Windows czy Menadżer zadań. Powyżej normalnego Normalny - standard w systemie Windows. Jeżeli tworzymy nowy proces lub wątek bez określonej wcześniej klasy priorytetu to standardowo, klasa priorytetu tych obiektów jest ustawiona na "normalny". Poniżej normalnego Niski - wątki takiego procesu wykonują się w momencie bezczynności systemu. Przykładem jest wygaszasz ekranu.
20
Wzgędne priorytety wątku Krytyczny Najlepszy Powyżej normalnego Normalny Poniżej normalnego Najgorszy Niski.
21
Ustalanie priorytetu właściwego Wzgledny priorytet wątku Klasa priorytetu procesu NiskiPon. Norm. NormalnyPow. Norm.WysokiCzasu rzecz. Krytyczny15 31 Najlepszy6810121526 Pow. norm. 579111425 Normalny468101324 Pon. norm.35791223 Najgorszy24681122 Niski1111116
22
Klasa priorytetu procesu REALTIME_PRIORITY_CLASS - czasu rzeczywistego. HIGH_PRIORITY_CLASS - wysoki. ABOVE_NORMAL_PRIORITY_CLASS powyżej normalnego. NORMAL_PRIORITY_CLASS - normalny. BELOW_NORMAL_PRIORITY_CLASS - poniżej normalnego. IDLE_PRIORITY_CLASS - niski.
23
Klasa priorytetu procesu DWORD GetPriorityClass( HANDLE hProcess); Odczyt: Modyfikacja BOOL SetPriorityClass( HANDLE hProcess, DWORD fdwPriority);
24
Priorytet względny wątku THREAD_PRIORITY_TIME_CRITICAL - krytyczny. THREAD_PRIORITY_HIGHEST - najlepszy. THREAD_PRIORITY_ABOVE_NORMAL - powyżej normalnego. THREAD_PRIORITY_NORMAL - normalny. THREAD_PRIORITY_BELOW_NORMAL - poniżej normalnego. THREAD_PRIORITY_LOWEST - najgorszy. THREAD_PRIORITY_IDLE - niski.
25
Priorytet względny wątku GetThreadPriority( HANDLE hThread) Odczyt: Modyfikacja SetThreadPriority( HANDLE hThread, int nPriority);
26
Synchronizacja
27
Metody synchronizacji Operacje atomowe Sekcje krytyczne Funkcje oczekujące Mutexy Semafory Zdarzenia Zegary oczekujące
28
Operacje Atomowe Czyli operacje niepodzielne. Każda instrukcja w języku wysokiego poziomu jest tłumaczona na wiele instrukcji maszynowych. Operacje atomowe zapewniają, że w czasie wykonywania tych instrukcji wątek nie zostanie wywłaszczony.
29
Operacje Atomowe InterlockedExchange, InterlockedExchange64 – przypisanie zmiennej wybranej wartości InterlockedIncrement, InterlockedIncrement64 – zwiększenie wartości zmiennej o 1 InterlockedDecrement, InterlockedDecrement64 – zmniejszenie wartości zmiennej o 1 InterlockedExchangeAdd, InterlockedExchangeAdd64 – dodanie do zmiennej dowolnej wartości całkowitej
30
Operacje Atomowe InterlockedComapreExchange, InterlockedExchangeAdd64 – porównanie wartości dwóch zmiennych InterlockedExchangePointer – zamiana wartości dwóch wskaźników, InterlockedCompareExchangePointer – porównanie wartości dwóch wskaźników.
31
Sekcja Krytyczna Jest rozszerzeniem operacji atomowych. Pozwala na objęcie nieprzerywalnością wykonania wybranego fragmentu funkcji wątku.
32
Sekcja Krytyczna Inicjalizacja: Zwolnienie zasobów: VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection); VOID DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
33
Sekcja Krytyczna Wejscie do sekcji krytycznej: Wyjście z sekcji krytycznej: VOID EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection); VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
34
Funkcje Oczekujace Zadaniem funkcji oczekujących jest oczekiwanie na przejście obiektu w stan sygnalizowany. Mechanizm ten obejmuje nie tylko wątki ale także szereg innych rodzajów obiektów, w tym opisywane dalej muteksy, semafory, zdarzenia i zegary oczekujące.
35
Funkcje Oczekujące DWORD WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds); Oczekiwanie na pojedynczy obiekt Oczekiwanie na grupę obiektów DWORD WaitForMultipleObjects( DWORD nCount, CONST HANDLE *lpHandles, BOOL bWaitAll, DWORD dwMilliseconds);
36
Muteksy Muteks jest obiektem, który posiada dwa stany: sygnalizowany i niesygnalizowany. W danej chwili właścicielem muteksu może być tylko jeden obiekt.
37
Tworzenie Muteksów lpMutexAttributes – wskaźnik na strukturę SECURITY _ ATTRIBUTES określającej atrybuty zabezpieczeń i dostępu do muteksu bInitialOwner – wartość TRUE powoduje, że właścicielem utworzonego muteksu jest wątek, w którym go utworzono, lpName – nazwa muteksu, podanie wartości NULL spowoduje utworzenie muteksu nienazwanego. HANDLE CreateMutex( LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCTSTR lpName );
38
Muteksy Zwolnienie Muteksu Pobranie uchwytu muteksu nazwanego HANDLE OpenMutex( DWORD dwDesiredAccess, BOOL bInheritHandle, LPCTSTR lpName ); BOOL ReleaseMutex( HANDLE hEvent );
39
Zdarzenia Zdarzenia są obiektami dwustanowymi: Od muteksów zdarzenia odróżnia możliwość regulacji sposobu przejścia zdarzenia w stan niesygnalizowany. Rodzaje odwołania: –Ręczne odwołanie funkcją ResetEvent() –Automatyczne odwołane po przepuszczeniu jednego oczekującego wątku
40
Tworzenie Zdarzenia HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCTSTR lpName ); lpEventAttributes – wskaźnik na strukturę SECURITY _ ATTRIBUTES
41
Tworzenie Zdarzenia bManualReset – określenie sposobu przechodzenia zdarzenia w stan niesygnalizowany; wartość TRUE ręczne; wartość FALSE automatyczne bInitialState – określenie czy po utworzeniu zdarzenie ma być w stanie sygnalizowanym (TRUE) czy też niesygnalizowanym (FALSE), lpName – nazwa zdarzenia, podanie wartości NULL spowoduje utworzenie zdarzenia nienazwanego
42
Zdarzenia Ręczne odwołanie zdarzenia Ustawienie zdarzenia BOOL SetEvent( HANDLE hEvent ); BOOL ResetEvent( HANDLE hEvent );
43
PulseEvent Powoduje przejście zdarzenia w stan sygnalizowany i natychmiastowy jego powrót w stan niesygnalizowany. Reakcja wątków oczekujących na zdarzenie zależy od wybranego sposobu przejścia zdarzenia w stan niesygnalizowany. Jeżeli jest to wykonywane ręcznie wywołanie PulseEvent przepuszcza wszystkie oczekujące wątki. W przeciwnym wypadku z puli wątków oczekujących na zasygnalizowanie zdarzenia wybierany jest tylko jeden
44
Semafory Przechowuje liczbę całkowitą dzieki której kontroluje ilość wątków wykonujących daną część programu. Każdy wątek wchodzący do sekcji zmniejsza wartość licznika o 1. Jeżeli wartość licznika osiągnie 0 więcej wątków nie zostanie wpuszczonych do czasu opuszczenia przez sekcji przez inny wątek.
45
Tworzenie Semafora lpSemaphoreAttributes – wskaźnik na strukturę SECURITY _ ATTRIBUTES HANDLE CreateSemaphore( LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCTSTR lpName );
46
Tworzenie Semafora lInitialCount – początkowa wartość licznika semafora, MaximumCount – maksymalna wielkość licznika semafora lpName – nazwa semafora, podanie wartości NULL spowoduje utworzenie semafora nienazwanego.
47
Zwolnienie Semafora BOOL ReleaseSemaphore( HANDLE hSemaphore, LONG lReleaseCount, LPLONG lpPreviousCount ); lReleaseCount – wartość odjęta od semafora lpPreviousCount – wskaźnik do zmiennej do zapisania poprzedniej wartości semafora
48
Zegary Oczekujące Zegar oczekujący przechodzi w stan sygnalizowany po upływie zadanego okresu czasu lub w określonych odstępach czasu z automatycznym powrotem do stanu niesygnalizowanego. Zegary umożliwiają np. regularne wywoływanie określonych wątków
49
Zegar Oczekujący lpTimerAttributes – wskaźnik na strukturę SECURITY _ ATTRIBUTES HANDLE WINAPI CreateWaitableTimer( LPSECURITY_ATTRIBUTES lpTimerAttributes, BOOL bManualReset, LPCTSTR lpTimerName )
50
Zegar Oczekujący bManualReset – wartość TRUE oznacza, że zegar jest ustawiany ręcznie; wartość FALSE oznacza, że zegar jest przestawiany w stan sygnalizowany automatycznie w określonych odstępach czasu z automatycznym powrotem do stanu niesygnalizowanego po wyjściu z funkcji oczekującej, lpTimerName – nazwa zegara, podanie wartości NULL spowoduje utworzenie zegara nienazwanego.
51
Zegar Oczekujący pDueTime – czas, po którym zegar przejdzie w stan sygnalizowany; BOOL WINAPI SetWaitableTimer( HANDLE hTimer, const LARGE_INTEGER *pDueTime, LONG lPeriod, PTIMERAPCROUTINE pfnCompletionRoutine, LPVOID lpArgToCompletionRoutine, BOOL fResume );
52
Zegar Oczekujący lPeriod – okres czasu (w milisekundach) po upływie którego zegar przechodzi w stan sygnalizowany; jeżeli podana wartość jest większa od zera, to zegar jest automatycznie uruchamiany co określony czas dopóki nie zostanie zatrzymany poprzez wywołanie funkcji CancelWaitableTimer lub ponownie aktywowany przy użyciu funkcji SetWaitableTime
Podobne prezentacje
© 2024 SlidePlayer.pl Inc.
All rights reserved.