Wielowątkowość: Tworzenie wątków roboczych
Wątek roboczy jest powszechnie używany do obsługi zadania w tle, które użytkownik nie powinien mieć zaczekać, aby kontynuować, używając aplikacji.Zadania, takie jak ponownego obliczania i drukowania w tle są dobrym przykładem wątków roboczych.Opis kroków niezbędnych do utworzenia wątku roboczego szczegółowe informacje na ten temat.Tematy obejmują:
Rozpoczęcie wątku
Wykonania kontroli funkcji
Przykład
Tworzenie wątku roboczego jest stosunkowo proste.Tylko dwie czynności, aby wątek uruchomiony: wykonywania funkcji kontrolnych oraz Rozpoczęcie wątku.Nie jest konieczne w celu uzyskania docelowej klasy z CWinThread.Może pochodzić od klasy, jeśli potrzebujesz specjalną wersję CWinThread, ale nie jest wymagane dla większości prostych wątków.Można użyć CWinThread bez zmian.
Rozpoczęcie wątku
Istnieją dwie wersje przeciążone AfxBeginThread: takie, które można tworzyć tylko wątków roboczych i który można utworzyć interfejsu użytkownika wątków i wątków roboczych.Aby rozpocząć wykonywanie wątku roboczego przy użyciu pierwszego przeciążenie, call AfxBeginThread, zawierającą następujące informacje:
Adres funkcji kontroli.
Parametr do przekazania do kontrolowania funkcji.
(Opcjonalnie) Żądany priorytet wątku.Wartością domyślną jest priorytet normalny.Aby uzyskać więcej informacji na temat poziomów priorytetu dostępne zobacz SetThreadPriority w Windows SDK.
(Opcjonalnie) Żądany rozmiar stosu wątku.Wartość domyślna to ten sam rozmiar stosu jako wątek, który.
(Opcjonalnie) CREATE_SUSPENDED Jeśli wątek ma być utworzony w stanie wstrzymania.Wartość domyślna jest równa 0 lub wątek uruchamia się normalnie.
(Opcjonalnie) Atrybuty żądanych zabezpieczeń.Wartością domyślną jest taki sam dostęp, jak wątek nadrzędny.Aby uzyskać więcej informacji o formacie informacji o zabezpieczeniach, zobacz SECURITY_ATTRIBUTES w Windows SDK.
AfxBeginThreadTworzy i inicjuje CWinThread obiektu dla Ciebie, uruchomi go i zwraca jego adres, więc można odwołać się do niego później.Kontrole są wprowadzane w czasie całej procedury upewnij się, że wszystkie obiekty są deallocated poprawnie niezastosowania się jakiejkolwiek części Tworzenie.
Wykonania kontroli funkcji
Funkcja kontroli definiuje wątku.Po wprowadzeniu tej funkcji wątek rozpoczyna się, a także po wydaniu, wątek kończy działanie.Ta funkcja powinna mieć następujący prototyp:
UINT MyControllingFunction( LPVOID pParam );
Parametr jest pojedynczą wartość.Wartość, którą otrzymuje ona w tym parametrze jest wartością, która została przekazana do konstruktora, podczas tworzenia obiektu wątku.Funkcja kontroli mogą interpretować tę wartość w jakikolwiek sposób, który wybiera.Mogą być traktowane jako wartość skalarną lub wskaźnika do struktury, zawierające wiele parametrów, lub można go zignorować.Jeśli parametr odwołuje się do struktury, struktura może służyć nie tylko do przekazywania danych od rozmówcy do wątku, ale również do przekazywania danych z powrotem wątku do obiektu wywołującego.Jeśli używasz takiej struktury do przekazywania danych do wywołującego, wątek musi powiadomić wywołujący, gdy wyniki są gotowe.Aby uzyskać informacje na temat komunikowania się z wątku roboczego do obiektu wywołującego, zobacz wielowątkowość: porady dotyczące programowania.
Gdy funkcja kończy działanie, gdy powinna zwrócić UINT wartość wskazującą, powód zakończenia zatrudnienia.Zazwyczaj ten kod wyjścia jest 0 do wskazania sukcesu pozostałe wartości wskazujące różnych błędów.Jest to czysto implementacji zależnych.Kilka wątków może utrzymywać liczniki użycia obiektów i zwraca bieżącą liczbę zastosowań tego obiektu.Aby zobaczyć, jak aplikacje mogą pobierać tę wartość, zobacz wielowątkowość: kończące wątki.
Istnieją pewne ograniczenia, co można zrobić w programie wielowątkowe zapisany przy użyciu biblioteki MFC.Aby uzyskać opis tych ograniczeń i inne porady dotyczące korzystania z wątków, zobacz wielowątkowość: porady dotyczące programowania.
Kontrolowanie przykład funkcji
Poniższy przykład pokazuje jak zdefiniować funkcję kontroli i używać go z innej części programu.
UINT MyThreadProc( LPVOID pParam )
{
CMyObject* pObject = (CMyObject*)pParam;
if (pObject == NULL ||
!pObject->IsKindOf(RUNTIME_CLASS(CMyObject)))
return 1; // if pObject is not valid
// do something with 'pObject'
return 0; // thread completed successfully
}
// inside a different function in the program
.
.
.
pNewObject = new CMyObject;
AfxBeginThread(MyThreadProc, pNewObject);
.
.
.