Udostępnij za pośrednictwem


Apartamenty wielowątkowane

W wielowątkowym modelu mieszkalnym wszystkie wątki w procesie, które zostały zainicjowane jako wolne wątki, znajdują się w jednym mieszkaniu. W związku z tym nie ma potrzeby marshalingu między wątkami. Wątki nie muszą pobierać i wysyłać komunikatów, ponieważ com nie używa komunikatów okna w tym modelu.

Wywołania metod obiektów w wielowątkowym mieszkaniu można uruchamiać w dowolnym wątku w mieszkaniu. Nie ma serializacji wywołań; wiele wywołań może wystąpić do tej samej metody lub do tego samego obiektu jednocześnie. Obiekty utworzone w wielowątkowym mieszkaniu muszą być w stanie obsługiwać wywołania metod z innych wątków w dowolnym momencie.

Ponieważ wywołania obiektów nie są serializowane w żaden sposób, współbieżność wielowątków obiektów oferuje najwyższą wydajność i wykorzystuje najlepszą zaletę sprzętu wieloprocesorowego na potrzeby międzywątkowego, międzyprocesowego i krzyżowego wywoływania maszyn. Oznacza to jednak, że kod dla obiektów musi zapewnić synchronizację w implementacjach interfejsu, zazwyczaj za pomocą elementów pierwotnych synchronizacji, takich jak obiekty zdarzeń, sekcje krytyczne, mutexy lub semafory, które zostały opisane w dalszej części tej sekcji. Ponadto, ponieważ obiekt nie kontroluje okresu istnienia wątków, które uzyskują do niego dostęp, żaden stan specyficzny dla wątku nie może być przechowywany w obiekcie (w magazynie lokalnym wątku).

Poniżej przedstawiono kilka ważnych zagadnień dotyczących synchronizacji wielowątków mieszkań:

  • Com zapewnia synchronizację połączeń tylko dla apartamentów jednowątkowych.
  • Wielowątkowe apartamenty nie odbierają połączeń podczas wykonywania wywołań (w tym samym wątku).
  • Wielowątkowe apartamenty nie mogą wykonywać wywołań zsynchronizowanych z danymi wejściowymi.
  • Wywołania asynchroniczne są konwertowane na wywołania synchroniczne w wielowątkowym mieszkaniach.
  • Filtr wiadomości nie jest wywoływany dla żadnego wątku w mieszkaniu wielowątkowym.

Aby zainicjować wątek jako dowolny wątek, wywołaj metodę CoInitializeEx, określając COINIT_MULTITHREADED. Aby uzyskać informacje na temat wątków serwera przetwarzania, zobacz In-Process Server Threading Issues.

Wielu klientów może jednocześnie wywoływać obiekt z różnych wątków, który obsługuje wątki wolne. W przypadku bezwątowych serwerów przetwarzania com za pośrednictwem podsystemu RPC tworzy pulę wątków w procesie serwera, a wywołanie klienta (lub wiele wywołań klienta) może być dostarczane przez dowolny z tych wątków w dowolnym momencie. Serwer poza procesem musi również implementować synchronizację w fabryce klas. Obiekty bezwątkowa mogą odbierać bezpośrednie wywołania z wielu wątków klienta.

Klient może wykonać pracę com w wielu wątkach. Wszystkie wątki należą do tego samego wielowątkowego mieszkania. Wskaźniki interfejsu są przekazywane bezpośrednio z wątku do wątku w wielowątkowym mieszkaniu, więc wskaźniki interfejsu nie są marshalowane między wątkami. Filtry komunikatów (implementacje IMessageFilter) nie są używane w wielowątkowym mieszkaniach. Wątek klienta zostanie zawieszony, gdy wywołanie COM do obiektów poza mieszkaniem zostanie wznowione po powrocie wywołania. Wywołania między procesami są nadal obsługiwane przez RPC.

Wątki inicjowane za pomocą modelu bezwątkowy muszą implementować własną synchronizację. Jak wspomniano wcześniej w tej sekcji, system Windows włącza tę implementację za pomocą następujących elementów pierwotnych synchronizacji:

  • Obiekty zdarzeń umożliwiają sygnalizowanie co najmniej jednego wątku, które wystąpiło zdarzenie. Każdy wątek w procesie może utworzyć obiekt zdarzenia. Dojście do zdarzenia jest zwracane przez funkcję tworzenia zdarzeń CreateEvent. Po utworzeniu obiektu zdarzenia wątki z uchwytem do obiektu mogą czekać przed kontynuowaniem wykonywania.
  • Sekcje krytyczne są używane w sekcji kodu, która wymaga wyłącznego dostępu do niektórych zestawów udostępnionych danych, zanim będzie można je wykonać i które są używane tylko przez wątki w ramach jednego procesu. Sekcja krytyczna jest jak kołowrotka, przez który może przechodzić tylko jeden wątek jednocześnie, działając w następujący sposób:
    • Aby zagwarantować, że nie więcej niż jeden wątek jednocześnie uzyskuje dostęp do udostępnionych danych, wątek podstawowy procesu przydziela globalną strukturę danych CRITICAL_SECTION i inicjuje jego składowe. Wątek wprowadzający sekcję krytyczną wywołuje funkcję EnterCriticalSection i modyfikuje elementy członkowskie struktury danych.
    • Wątek próbujący wprowadzić sekcję krytyczną wywołuje EnterCriticalSection, który sprawdza, czy struktura danych CRITICAL_SECTION została zmodyfikowana. Jeśli tak, inny wątek znajduje się obecnie w sekcji krytycznej, a kolejny wątek zostanie uśpiony. Wątek pozostawiając sekcję krytyczną wywołuje LeaveCriticalSection, co resetuje strukturę danych. Gdy wątek opuści sekcję krytyczną, system wznawia jeden z wątków uśpienia, który następnie przechodzi do sekcji krytycznej.
  • Mutexes wykonuje tę samą funkcję co sekcja krytyczna, z tą różnicą, że mutex jest dostępny dla wątków działających w różnych procesach. Posiadanie obiektu mutex jest jak posiadanie podłogi w debacie. Proces tworzy obiekt mutex, wywołując funkcję CreateMutex, która zwraca uchwyt. Pierwszy wątek żądający obiektu mutex uzyskuje własność. Po zakończeniu wątku z mutex, własność przechodzi do innych wątków w pierwszej kolejności, najpierw obsługiwane.
  • Semafory są używane do utrzymania liczby odwołań dla niektórych dostępnych zasobów. Wątek tworzy semafor dla zasobu, wywołując funkcję CreateSemaphore i przekazując wskaźnik do zasobu, początkową liczbę zasobów i maksymalną liczbę zasobów. Ta funkcja zwraca uchwyt. Wątek żądający zasobu przekazuje dojście semafora w wywołaniu funkcji WaitForSingleObject. Obiekt semafora sonduje zasób, aby określić, czy jest dostępny. Jeśli tak, semafor dekreuje liczbę zasobów i wznawia oczekujący wątek. Jeśli liczba wynosi zero, wątek pozostaje w stanie uśpienia, dopóki inny wątek nie zwolni zasobu, co spowoduje, że semafor zwiększa liczbę do jednej.

uzyskiwanie dostępu do interfejsów w apartamentach

wybieranie modelu wątkowego

problemy z wątkami serwera In-Process

procesy, wątki i apartamenty

Single-Threaded i komunikacja wielowątkowa

Single-Threaded Apartamenty