Udostępnij za pośrednictwem


Ulepszenia kolejki pracy i wątkowania

W tym temacie opisano ulepszenia w systemie Windows 8 dla kolejek roboczych i wątków na platformie Microsoft Media Foundation.

Zachowanie systemu Windows 7

W tej sekcji przedstawiono podsumowanie zachowania kolejek roboczych programu Media Foundation w systemie Windows 7.

Kolejki robocze

Platforma Media Foundation tworzy kilka standardowych kolejek roboczych. Tylko dwa są udokumentowane jako przeznaczone do użytku ogólnego aplikacji:

  • MFASYNC_CALLBACK_QUEUE_STANDARD
  • MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION

Aplikacja lub składnik może przydzielić nowe kolejki robocze, wywołując MFAllocateWorkQueue lub MFAllocateWorkQueueEx. Funkcja MFAllocateWorkQueueEx definiuje dwa typy kolejek roboczych:

  • MF_STANDARD_WORKQUEUE tworzy kolejkę roboczą bez pętli komunikatów.
  • MF_WINDOW_WORKQUEUE tworzy kolejkę roboczą z pętlą komunikatów.

Aby utworzyć kolejkę elementu roboczego, wywołaj MFPutWorkItem lub MFPutWorkItemEx. Platforma wykonuje element roboczy, wywołując implementację interfejsu IMFAsyncCallback. W systemie Windows 7 i starszych platforma tworzy jeden wątek na kolejkę roboczą.

Obsługa usługi MMCSS

Usługa Multimedia Class Scheduler Service (MMCSS) zarządza priorytetami wątków, dzięki czemu aplikacje multimedialne uzyskują regularne wycinki czasu procesora CPU bez odmowy zasobów procesora CPU do aplikacji o niższym priorytcie. Program MMCSS definiuje zestaw zadań , które mają różne profile wykorzystania procesora CPU. Gdy wątek łączy zadanie MMCSS, program MMCSS ustawia priorytet wątku na podstawie kilku czynników:

  • Podstawowy priorytet zadania, który jest ustawiony w rejestrze.
  • Względny priorytet wątku, który jest ustawiany w czasie wykonywania przez wywołanie AvSetMmThreadPriority.
  • Różne cechy czasu wykonywania, takie jak to, czy aplikacja znajduje się na pierwszym planie, oraz ile czasu procesora CPU zużywa wątki w każdej klasie MMCSS.

Aplikacja może zarejestrować kolejkę roboczą w programie MMCSS, wywołując MFBeginRegisterWorkQueueWithMMCSS. Ta funkcja przyjmuje identyfikator kolejki pracy, klasę MMCSS (nazwę zadania) i identyfikator zadania MMCSS. Wewnętrznie wywołuje AvSetMmThreadCharacteristics z nazwą zadania i identyfikatorem zadania. Po zarejestrowaniu kolejki roboczej w programie MMCSS można uzyskać identyfikator klasy i zadania, wywołując MFGetWorkQueueMMCSSClass i MFGetWorkQueueMMCSSTaskId.

sesji multimediów zapewnia nieco wyższy poziom dostępu do tych interfejsów API za pośrednictwem interfejsuIMFWorkQueueServices. Ten interfejs udostępnia dwie podstawowe metody:

Metoda Opis
BeginRegisterPlatformWorkQueueWithMMCSS Rejestruje kolejkę roboczą za pomocą zadania MMCSS. Ta metoda jest zasadniczo cienką otoką wokół MFBeginRegisterWorkQueueWithMMCSS, ale można przekazać wartość MFASYNC_CALLBACK_QUEUE_ALL, aby zarejestrować wszystkie kolejki robocze platformy jednocześnie.
BeginRegisterTopologyWorkQueuesWithMMCSS Rejestruje gałąź topologii w kolejce roboczej.

 

Aby zarejestrować gałąź topologii, wykonaj następujące czynności.

  1. Ustaw atrybut MF_TOPONODE_WORKQUEUE_ID w węźle źródłowym dla gałęzi. Użyj dowolnej wartości zdefiniowanej przez aplikację.
  2. Opcjonalnie ustaw MF_TOPONODE_WORKQUEUE_MMCSS_CLASS, aby dołączyć kolejkę roboczą do zadania MMCSS.
  3. Wywołaj BeginRegisterTopologyWorkQueuesWithMMCSS na rozpoznaną topologię.

Sesja multimediów przydziela nową kolejkę pracy dla każdej unikatowej wartości MF_TOPONODE_WORKQUEUE_ID. Dla każdej gałęzi topologii operacje potoku asynchronicznego są wykonywane w kolejce roboczej przypisanej do gałęzi.

IMFRealTimeClient

Interfejs IMFRealTimeClient jest przeznaczony dla składników potoku, które tworzą własne wątki lub używają kolejek roboczych na potrzeby operacji asynchronicznych. Sesja multimediów używa tego interfejsu do powiadamiania składnika potoku o prawidłowym zachowaniu w następujący sposób:

Zazwyczaj składnik potoku używa wątku lub kolejki roboczej do wykonywania zadań asynchronicznych, ale nie obu.

Ulepszenia systemu Windows 8

Wielowątkowane kolejki robocze

W systemie Windows 8 program Media Foundation obsługuje nowy typ kolejki pracy o nazwie kolejki wielowątkowej. Kolejka wielowątkowa używa puli wątków systemowych do wysyłania elementów roboczych. Kolejka wielowątkowa jest skalowana lepiej niż poprzednie kolejki jednowątkowe. Na przykład

  • Kilka składników może współużytkować kolejkę wielowątkową bez blokowania siebie, co wymaga utworzenia mniejszej liczby wątków.

  • Elementy robocze są zoptymalizowane, aby uniknąć przełączników kontekstowych, jeśli zdarzenie jest już ustawione. Jest to bardziej wydajne niż tworzenie własnych wątków do oczekiwania na zdarzenia.

W przypadku korzystania z IMFRealTimeClientExaplikacje powinny unikać uruchamiania wątków i zamiast tego powinny używać kolejek roboczych. W tym celu aplikacje powinny implementować SetWorkQueueEx i nie używać RegisterThreads i UnregisterThreads.

Po zainicjowaniu platformy Media Foundation tworzy kolejkę wielowątkową z identyfikatorem MFASYNC_CALLBACK_QUEUE_MULTITHREADED.

Kolejka wielowątkowy nie serializuje elementów roboczych. Za każdym razem, gdy wątek z puli wątków stanie się dostępny, zostanie wysłany następny element roboczy w kolejce. Obiekt wywołujący musi upewnić się, że praca jest serializowana poprawnie. Aby to ułatwić, program Media Foundation definiuje kolejkę szeregową pracy. Kolejka szeregowa opakowuje kolejną kolejkę pracy, ale gwarantuje w pełni serializowane wykonanie. Następny element w kolejce nie jest wysyłany do momentu zakończenia poprzedniego elementu.

Poniższy kod tworzy kolejkę serializatora przez kolejkę wielowątkową platformy.

DWORD workQueueID;
hr = MFAllocateSerialWorkQueue(MFASYNC_CALLBACK_QUEUE_MULTITHREADED, &workQueueID); 

Więcej niż jedna kolejka szeregowa może opakowować tę samą kolejkę wielowątkową. Kolejki szeregowe następnie współużytkują tę samą pulę wątków, a serializowane wykonywanie jest wymuszane w każdej kolejce.

Standardowe kolejki robocze, które istniały przed systemem Windows 8, są teraz implementowane jako szeregowe kolejki robocze, które opakowują kolejkę wielowątkową platformy. Ta zmiana zachowuje zgodność z poprzednimi wersjami.

Kolejki zadań udostępnionych

Aby prawidłowo pracować z harmonogramem jądra, należy mieć jedną wielowątkową kolejkę pracy dla każdego używanego zadania MMCSS. Platforma Media Foundation przydziela je zgodnie z potrzebami, maksymalnie jeden na zadanie MMCSS, na proces. Aby pobrać udostępnioną kolejkę pracy dla określonego zadania MMCSS, wywołaj MFLockSharedWorkQueue i określ nazwę zadania. Funkcja wyszukuje nazwę zadania w tabeli. Jeśli kolejka robocza jeszcze nie istnieje dla tego zadania, funkcja przydziela nową kolejkę pracy mt i natychmiast dołącza ją do zadania MMCSS. Jeśli kolejka robocza już istnieje dla tego zadania, funkcja zwraca identyfikator istniejącej kolejki roboczej.

Kolejka oczekiwania

Kolejka oczekiwania to specjalna kolejka robocza platformy, która czeka na zdarzenia, które mają być zasygnalizowane. Jeśli składnik musi poczekać na zasygnalizowane zdarzenie, może użyć kolejki oczekiwania zamiast utworzyć wątek procesu roboczego, aby czekać na zdarzenie.

Aby użyć kolejki oczekiwania, wywołaj MFPutWaitingWorkItem. Parametry obejmują dojście zdarzeń i wskaźnik IMFAsyncResult. Gdy zdarzenie zostanie zasygnalizowane, kolejka oczekiwania wywołuje wywołanie zwrotne. Istnieje jedna kolejka oczekiwania na platformę; aplikacje nie mogą tworzyć własnych kolejek oczekiwania.

Ulepszenia obsługi usługi MMCSS

Następujące nowe funkcje platformy Media Foundation odnoszą się do usługi MMCSS.

Funkcja Opis
MFBeginRegisterWorkQueueWithMMCSSEx Rejestruje kolejkę roboczą w usłudze MMCSS. Ta funkcja zawiera parametr określający względny priorytet wątku. Ta wartość jest tłumaczona wewnętrznie na wywołanie AvSetMmThreadPriority.
MFGetWorkQueueMMCSSPriority Wykonuje zapytanie o priorytet kolejki roboczej.
MFRegisterPlatformWithMMCSS Rejestruje wszystkie kolejki robocze platformy za pomocą zadania MMCSS. Ta funkcja jest podobna do metody IMFWorkQueueServices::BeginRegisterPlatformWorkQueueWithMMCSS, ale można jej użyć bez tworzenia wystąpienia sesji multimediów. Ponadto funkcja zawiera parametr określający priorytet wątku podstawowego.

 

Aplikacje korzystające z sesji multimediów powinny ustawić atrybut MF_TOPONODE_WORKQUEUE_MMCSS_CLASS na wartość "Audio" dla gałęzi renderowania audio. Ustaw atrybut na "Odtwarzanie" dla gałęzi renderowania wideo.

IMFRealTimeClientEx

Interfejs IMFRealTimeClientEx zastępuje element IMFRealTimeClient dla składników potoku wykonujących operacje asynchroniczne.

Metoda Opis
RegisterThreadsEx Powiadamia składnik o zarejestrowaniu swoich wątków w programie MMCSS. Ta metoda jest równoważna IMFRealTimeClient::RegisterThreads, ale dodaje parametr priorytetu wątku podstawowego.
SetWorkQueueEx Powiadamia składnik o użyciu określonej kolejki roboczej. Ta metoda jest równoważna IMFReadTimeClient::SetWorkQueue, ale dodaje parametr priorytetu elementu roboczego.
UnregisterThreads Powiadamia składnik, aby wyrejestrować jego wątki z usługi MMCSS. Ta metoda jest identyczna z metodą IMFRealTimeClient::UnregisterThreads.

 

Składniki potoku powinny używać kolejek roboczych i nie powinny tworzyć wątków procesów roboczych z następujących powodów:

  • Kolejki robocze są skalowane lepiej, ponieważ używają pul wątków systemu operacyjnego.
  • Platforma obsługuje szczegóły rejestrowania kolejek roboczych w programie MMCSS.
  • Wątek procesu roboczego może łatwo spowodować zakleszczenie, które jest trudne do debugowania.

Ponadto rozważ użycie kolejki pracy serializatora, jeśli chcesz serializować operacje asynchroniczne.

Gałęzie topologii

Jeśli atrybut MF_TOPONODE_WORKQUEUE_MMCSS_CLASS rejestruje gałąź topologii z usługą MMCSS, w systemie Windows 8 sesja multimediów używa udostępnionych kolejek roboczych usługi MT. We wcześniejszych wersjach systemu Windows sesja multimediów przydzieliła nową kolejkę pracy.

Dwa nowe atrybuty są definiowane do rejestrowania gałęzi topologii w programie MMCSS.

Atrybut Opis
MF_TOPONODE_WORKQUEUE_MMCSS_PRIORITY Określa priorytet wątku podstawowego.
MF_TOPONODE_WORKQUEUE_ITEM_PRIORITY Określa priorytet elementu roboczego.

 

Zalecenia

  • Aplikacje korzystające z sesji multimediów powinny ustawić MF_TOPONODE_WORKQUEUE_MMCSS_CLASS na "Audio" dla gałęzi renderowania audio i "Odtwarzanie" dla gałęzi renderowania wideo.
  • Aplikacje korzystające z sesji multimediów powinny wywoływać IMFWorkQueueServices::BeginRegisterTopologyWorkQueuesWithMMCSS w topologii.
  • W przypadku składników potoku zalecane są kolejki robocze zamiast wątków roboczych. Jeśli składnik używa kolejek roboczych lub wątków roboczych, zaimplementuj IMFRealTimeClientEx.
  • Nie twórz kolejek pracy prywatnej, ponieważ powoduje to porażkę celu kolejek roboczych platformy. Użyj kolejki wielowątkowej platformy lub kolejki szeregowej, która opakowuje kolejkę wielowątkową platformy.
  • Jeśli musisz serializować operacje asynchroniczne, użyj kolejki szeregowej.

Streszczenie

Następujące interfejsy API platformy Media Foundation, które odnoszą się do wątków i kolejek roboczych, są nowe dla systemu Windows 8.

kolejek roboczych