Udostępnij za pośrednictwem


Wielowątkowość: jak używać klas synchronizacji

Synchronizowanie dostęp do zasobów między wątków jest to typowy problem występujący podczas pisania aplikacji wielowątkowych.Posiadanie dwóch lub więcej wątków jednocześnie dostęp do tych samych danych może prowadzić do niepożądanych i nieprzewidywalne rezultaty.Na przykład jeden wątek może aktualizować zawartość struktury, podczas gdy inny wątek odczytuje zawartość tę samą strukturę.Nie wiadomo, jakie dane otrzymają wątku czytania: stare dane, nowo zapisanych danych lub ewentualnie kombinacji obu.MFC udostępnia wiele synchronizacji oraz synchronizacji klas dostępu do pomocy w rozwiązaniu tego problemu.W tym temacie wyjaśniono klasy dostępne i jak z nich korzystać do tworzenia klas wątków w typowych aplikacji wielowątkowych.

Typowa aplikacja wielowątkowe ma klasy, która reprezentuje zasób dzielony pomiędzy wątkami.Klasa właściwie zaprojektowane, pełni wątków nie wymaga do wywołania dowolnej funkcji synchronizacji.Wszystko odbywa się wewnętrznie do klasy, co umożliwia skoncentrowanie się na jak najlepsze wykorzystanie klasy, nie na temat jak może uzyskać uszkodzony.Aby scalić klasy synchronizacji do klasy zasobu jest skuteczne techniki tworzenia klasy pełni wątków.Scalanie klas synchronizacji w klasie udostępnionego jest dość proste.

Na przykład podjąć aplikację, która utrzymuje listę połączonych kont.Aplikacja ta pozwala maksymalnie trzy konta należy zbadać w osobnych oknach, ale mogą być aktualizowane tylko jeden w każdej chwili w szczególności.Po zaktualizowaniu konto zaktualizowane dane są przesyłane przez sieć do archiwum danych.

Ten przykład aplikacja wykorzystuje wszystkie trzy typy klas synchronizacji.Ponieważ pozwala maksymalnie trzy konta zostały poddane kontroli w tym samym czasie, używa CSemaphore Aby ograniczyć dostęp do trzech obiektów widoku.Podczas próby wyświetlenia czwartego konta wystąpienia aplikacji, albo czeka, aż jeden z pierwszych trzech oknach zostaje zamknięty lub nie jest on.Po zaktualizowaniu konto używane przez aplikację CCriticalSection do zapewnienia, że w danej chwili jest aktualizowany tylko jedno konto.Po aktualizacji zakończy się pomyślnie, sygnalizuje klasy CEvent, który uwalnia wątku oczekiwania na zdarzenia być informowany.Ten wątek wysyła nowe dane do archiwum danych.

Projektowania klas wątków

Aby klasa pełni wątków, najpierw dodać klasy synchronizacji odpowiednie do klas udostępnionego jako element członkowski danych.W poprzednim przykładzie zarządzania kontami CSemaphore element członkowski danych zostanie dodane do widoku klasy, CCriticalSection element członkowski danych zostanie dodane do klasę połączone listy i CEvent element członkowski danych zostanie dodane do klasy magazynowania danych.

Następnie należy dodać synchronizacji wywołania wszystkich funkcji elementów członkowskich, które modyfikują dane w klasie lub uzyskać dostęp do zasobów kontrolowanych.W każdej funkcji, należy utworzyć jedną CSingleLock lub CMultiLock object i wywołać tego obiektu Lock funkcji.Gdy obiekt Zablokuj wykracza poza zakres i jest niszczony, destruktor obiektu wywołuje Unlock dla Ciebie, zwalniając zasobu.Oczywiście, można wywołać Unlock bezpośrednio Jeśli chcesz.

Projektowanie klasy wątków w ten sposób pozwala na używany w aplikacji wielowątkowych jako łatwo jako klasa non wątków, ale o wyższym poziomie bezpieczeństwa.Encapsulating synchronizacji obiektu i obiektu synchronizacji dostępu do klasy zasobu zawiera wszystkie zalety programowania pełni wątków bez ceł zwrotnych utrzymywanie synchronizacji kodu.

Poniższy przykład kodu pokazuje tej metody przy użyciu element członkowski danych, m_CritSection (typu CCriticalSection), a zadeklarowanych w klasie zasobu udostępnionego i CSingleLock obiektu.Synchronizacja zasobu udostępnionego (pochodzące z CWinThread) jest próba tworząc CSingleLock obiektu przy użyciu adresu m_CritSection obiektu.Próby zasób i, jeżeli uzyskano, praca jest wykonywana na obiektu współużytkowanego.Po zakończeniu pracy tego zasobu jest odblokowany z wezwaniem do Unlock.

CSingleLock singleLock(&m_CritSection);
singleLock.Lock();
// resource locked
//.usage of shared resource...

singleLock.Unlock();

[!UWAGA]

CCriticalSection, w przeciwieństwie do innych klas MFC synchronizacji, nie ma opcji żądania lock czasowym.Okres oczekiwania wątku stać się wolne jest nieograniczony.

Wady tej metody są, że klasa będzie nieco wolniej niż tej samej klasy bez obiektów synchronizacji dodane.Ponadto jeśli istnieje szansa, że więcej niż jeden wątek może usunąć obiekt, scalone podejście może nie zawsze działać.W tej sytuacji jest lepiej jest utrzymywać osobne synchronizacji obiektów.

Aby uzyskać informacje dotyczące ustalania klasy, które synchronizacji do wykorzystania w różnych sytuacjach, zobacz wielowątkowość: kiedy należy używać klasy synchronizacji.Aby uzyskać więcej informacji na temat synchronizacji, zobacz synchronizacji w Windows SDK.Aby uzyskać więcej informacji o obsłudze wielowątkowości w MFC, zobacz wielowątkowość z C++ i MFC.

Zobacz też

Koncepcje

Wielowątkowość z C++ i MFC