Wielowątkowość
klasa CWinThread
|
|
-
-
Proces - wykonywana instancja (instance)
aplikacji
-
Wątek - ścieżka wykonywania w
procesie
-
Z punktu widzenia API Windows
wszystkie wątki są takie same, natomiast w MFC można wyróżnić
dwa rodzaje wątków:
-
Wszystkie wątki aplikacji MFC
powinny wykorzystywać klasę CWinThread
[początek strony]
-
-
Zwykle są używane do obsługi możliwości,
jakie ma użytkownik, odpowiadają na komunikaty i zdarzenia przez
niego generowane
Aplikacja
(obiekt klasy CWinApp) jest także wątkiem interfejsu użytkownika
Schemat wykorzystania wątków
interfejsu użutkownika:
-
utworzyć klasę wątku
(dziedziczącą z CWinThread)
- musi być zadeklarowana i zaimplementowana z dynamicznym
tworzeniem (makra DECLARE_DYNCREATE i IMPLEMENT_DYNCREATE)
-
nadpisać potrzebne funkcje
wirtualne:
- CWinThread::InitInstance - inicjalizacja przed
uruchomieniem, musi być nadpisana
- CWinThread::ExitInstance - ostatnia funkcja przed
zakończeniem pracy wątku, zwykle nadpisywana
- CWinThread::Run - funkcja kontrolna wątku, rzadko
nadpisywana
- CWinThread::OnIdle - wywoływana gdy wątkowi brakuje
czynności do wykonania, rzadko nadpisywana
- CWinThread::PreTranslateMessage - filtruje komunikaty
przed wysłaniem ich do funkcji CWinThread::TranslateMessage
i CWinThread::DispatchMessage, rzadko nadpisywana
- CWinThread::ProcessWndProcException - obsługa niewyłapanych
wyjątków, rzadko nadpisywana
-
przy pomocy funkcji AfxBeginThread (z
parametrem określającym klasę wątku) utworzyć obiekt wątku i
uruchomić go
- funkcja ta zwraca wskaźnik do utworzonego wątku
-
aby zakończyć wątek wywołać
PostQuitMessage z parametrem określającym kod wyścia
wątku
-
pobrać kod wyjścia wątku można
przy pomocy funkcji GetExitCodeThread z parametrem CWinThread::m_hThread
- możliwe jest to tylko, jeśli flaga wątku CWinThread::m_bAutoDelete
była ustawiona na FALSE, co zapobiega automatycznemu usunięciu
wątku po zakończeniu jego pracy
[początek strony]
-
-
Są to wątki wykorzystywane zwykle
tylko do przeprowadzenia obliczeń, które nie potrzebują
interfejsu użytkownika
Schemat wykorzystania wątków
roboczych:
-
utworzyć funkcję wątku
- o prototypie: UINT
ControllingFunction( LPVOID pParam )
- parametrem tej funkcji jest wartość argumentu
przekazywanego do konstruktora podczas tworzenia wątku (może
to być wartość lub wskaźnik do struktury)
- wartością zwracaną przez funkcję powinien być kod wyjścia,
zwykle 0 jako sukces
-
uruchomić wątek przy pomocy
funkcji AfxBeginThread (z parametrem określającym
funkcję wątku)
-
zakończyć pracę wątku można
w jeden ze sposobów:
- zakończyć wykonywanie funkcji wątku
- wywołać z wątku funkcję AfxEndThread
[początek strony]
-
-
W przypadku wymiany danych pomiędzy
wątkami może być konieczna synchronizacja, aby zapobiec
konfliktom podczas dostępu do danych
Klasy obiektów synchronizacji:
-
CSyncObject
- wirtualna klasa bazowa wszystkich obiektów
synchronizacji
-
CSemaphore
- dostęp do ograniczonej (większej niż 1) liczby zasobów
- konkurujące wątki mogą być z różnych procesów
-
CMutex
- dostęp do jednego zasobu (tylko jeden z wątków może
w jednej chwili korzystać z tego zasobu)
- wątki mogą być z różnych procesów
-
CCriticalSection
- jeden zasób
- wątki muszą być z jednego procesu
-
CEvent
- daje możliwość zawiadomienia wątku o czymś
- stosowane, gdy wątek musi zaczekać na coś
-
Klasy obiektów synchronizacji dostępu:
-
CSingleLock - dla
pojedynczego obiektu synchronizacji
-
CMultiLock - dla wielu
obiektów synchronizacji
-
schemat wykorzystania:
- utworzyć obiekt lub obiekty synchronizacji i przekazać do
tworzonego obiektu synchronizacji dostępu
- przy pomocy CSingleLock::Lock lub CMultiLock::Lock
czekać na dostęp
- po otrzymaniu dostępu wykonać pożądane czynności
- oddać dostęp przy pomocy CSingleLock::Unlock lub CMultiLock::Unlock
[początek strony]
-
CObject
- informacja w trakcie wykonywania, dynamiczne tworzenie, serializacja
CCmdTarget - obsługa
komunikatów Windows
CWinThread
CSyncObject
CCriticalSection
CEvent
CMutex
CSemaphore
CSingleLock
CMultiLock
[początek strony]
|