Pisanie wielowątkowego programu Win32
Pisząc program przy użyciu wielu wątków, musi koordynować ich działania i wykorzystania zasobów programu.Należy się również upewnić, że każdy wątek otrzymuje swój własny stos.
Udostępnianie wspólnych zasobów między wątków
[!UWAGA]
Omówienie podobne z punktu widzenia MFC, zobacz Wielowątkowość: porady dotyczące programowania i Wielowątkowość: kiedy używać klas synchronizacji.
Każdy wątek posiada swój własny stos i rejestruje swoją własną kopią procesora.Inne zasoby, takie jak pliki, dane statyczne i pamięć sterty są współużytkowane przez wszystkie wątki w procesie.Wątki za pomocą tych wspólnych zasobów musi być synchronizowany.Win32 oferuje kilka metod do synchronizowania zasobów, w tym semafory, sekcji krytycznych, zdarzenia i muteksy.
Wiele wątków uzyskują dostęp do danych statycznych, program musi przewidywać konflikty zasobów możliwe.Należy wziąć pod uwagę program, gdzie jeden wątek aktualizuje struktury danych statycznych zawierające x,y współrzędne elementy mają być wyświetlane przez inny wątek.Jeśli wątek aktualizacja zmienia x koordynowania i jest zastępowane zanim można zmienić y współrzędnych, wątek wyświetlacz może być zaplanowane przed y współrzędnych jest aktualizowana.Element będzie wyowietlana w niewłaściwej lokalizacji.Aby uniknąć tego problemu, należy przy użyciu semaforów do kontrolowania dostępu do struktury.
Mutex (skrót od mutręcz expowstałej) jest sposobem komunikowania się wśród wątków lub procesów, które są wykonywane asynchronicznie sobie nawzajem.Komunikat ten jest zwykle używany do koordynować działania wielu wątków lub procesów, zazwyczaj poprzez kontrolowanie dostępu do zasobu udostępnianego przez blokowanie i odblokowywanie zasobów.Aby rozwiązać ten problem x,y problem z aktualizacją współrzędnych, wątek aktualizacja ustawia mutex, co oznacza, że struktura danych używana przed przeprowadzeniem aktualizacji.Mutex to oczywiste po obu współrzędne została przetworzona.Wątek wyświetlania muszą czekać na być jasne przed aktualizacją wyświetlania obiektu mutex.Ten proces trwa oczekiwanie na obiektu mutex jest często nazywany blokowanie na obiektu mutex, ponieważ proces jest zablokowany i nie może kontynuować, dopóki nie czyści obiektu mutex.
Program Bounce.c się w Przykładowy program więlowątkowy w języku C używa obiektu mutex o nazwie ScreenMutex do koordynowania aktualizacje ekranu.Zawsze jeden z wątków, ekran jest gotowy do zapisu do ekranu, wywołuje WaitForSingleObject z uchwytem do ScreenMutex i stałej NIESKOŃCZONE aby wskazać, że WaitForSingleObject rozmowy należy zablokować obiektu mutex i limitu czasu nie.Jeśli ScreenMutex jest pusta, funkcja wait ustawia obiektu mutex, więc inne wątki nie mogą kolidować z wyświetlaniem i kontynuuje wykonywanie wątku.W przeciwnym razie wątek blokuje dopóki nie czyści obiektu mutex.Po zakończeniu aktualizacji ekranu, zwalnia mutex przez wywołanie ReleaseMutex.
Zostanie wyświetlony ekran i dane statyczne są tylko dwa z zasobów wymaga starannego zarządzania.Na przykład program może mieć wiele wątków, uzyskiwanie dostępu do tego samego pliku.Ponieważ inny wątek może być przeniesione wskaźnika pliku, każdy wątek musi zresetować wskaźnika pliku przed Odczyt lub zapis.Ponadto każdy wątek powinien upewnić się, że nie jest zastępowane między czas to określa położenie wskaźnika i uzyskuje dostęp do pliku.Wątki te należy używać semafor do koordynowania dostępu do pliku, umieszczając każdy dostęp do plików z WaitForSingleObject i ReleaseMutex wywołań.Poniższy kod ilustruje tę technikę:
HANDLE hIOMutex= CreateMutex (NULL, FALSE, NULL);
WaitForSingleObject( hIOMutex, INFINITE );
fseek( fp, desired_position, 0L );
fwrite( data, sizeof( data ), 1, fp );
ReleaseMutex( hIOMutex);
Stosy wątku
Cały obszar stosu domyślnej aplikacji jest przydzielany do pierwszego wątku do wykonania, który jest znany jako wątku 1.W rezultacie należy określić, ile pamięci, aby przydzielić na osobny stos dla każdego wątku dodatkowy program potrzebuje.System operacyjny przydziela miejsce na dodatkowe stosu wątku, w razie potrzeby, ale należy określić wartość domyślną.
Pierwszy argument _beginthread wywołanie jest wskaźnik do BounceProc funkcja, która wykonuje wątki.Drugi argument określa domyślny rozmiar stosu wątku.Ostatni argument jest numer identyfikacyjny, który jest przekazywany do BounceProc.BounceProc używa numeru ID do materiału siewnego generator liczb losowych i aby wybrać atrybut koloru dla wątku i wyświetlić znak.
Wątki, które wykonywania wywołań do biblioteki wykonawczej C lub interfejsu Win32 API musi umożliwiać zabraknąć miejsca na stosie dla biblioteki i funkcji API, które wywołują.C printf funkcja wymaga więcej niż 500 bajtów miejsca na stosie, a powinien mieć 2K dostępnego miejsca na stosie podczas wywoływania procedur Win32 API.
Ponieważ każdy wątek ma własny stos, można uniknąć potencjalnych konfliktów nad elementami danych przy użyciu możliwie mało statycznych danych.Projekt programu, aby używać zmiennych stosu automatyczne dla wszystkich danych, które mogą być prywatne do wątku.Zmienne globalne tylko w programie Bounce.c są muteksy lub zmienne, które nigdy nie zmieniają się po ich inicjowaniu.
Win32 zapewnia także lokalnej wątku magazynu (TLS) do przechowywania danych na wątek.Aby uzyskać dodatkowe informacje, zobacz Lokalny magazyn wątków (TLS).