Freigeben über


Verbesserungen bei Der Arbeitswarteschlange und Threading

In diesem Thema werden Verbesserungen in Windows 8 für Arbeitswarteschlangen und Threading in der Microsoft Media Foundation-Plattform beschrieben.

Windows 7-Verhalten

In diesem Abschnitt wird das Verhalten von Media Foundation-Arbeitswarteschlangen in Windows 7 zusammengefasst.

Arbeitswarteschlangen

Die Media Foundation-Plattform erstellt mehrere Standardarbeitswarteschlangen. Nur zwei werden als allgemeine Anwendungsverwendung dokumentiert:

  • MFASYNC_CALLBACK_QUEUE_STANDARD
  • MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION

Eine Anwendung oder Komponente kann neue Arbeitswarteschlangen zuordnen, indem sie MFAllocateWorkQueue oder MFAllocateWorkQueueExaufrufen. Die funktion MFAllocateWorkQueueEx definiert zwei Arten von Arbeitswarteschlangen:

  • MF_STANDARD_WORKQUEUE erstellt eine Arbeitswarteschlange ohne Nachrichtenschleife.
  • MF_WINDOW_WORKQUEUE erstellt eine Arbeitswarteschlange mit einer Nachrichtenschleife.

Um eine Arbeitsaufgabe in die Warteschlange zu stellen, rufen Sie MFPutWorkItem- oder MFPutWorkItemEx-auf. Die Plattform führt die Arbeitsaufgabe aus, indem sie die vom Aufrufer bereitgestellte Implementierung von IMFAsyncCallbackaufruft. In Windows 7 und früheren Versionen erstellt die Plattform einen Thread pro Arbeitswarteschlange.

MMCSS-Unterstützung

Der Multimedia Class Scheduler Service (MMCSS) verwaltet Threadprioritäten, sodass Multimediaanwendungen normale Segmente der CPU-Zeit erhalten, ohne CPU-Ressourcen für Anwendungen mit niedrigerer Priorität zu verweigern. MMCSS definiert eine Reihe von Aufgaben mit unterschiedlichen CPU-Auslastungsprofilen. Wenn ein Thread eine MMCSS-Aufgabe verknüpft, legt MMCSS die Priorität des Threads basierend auf mehreren Faktoren fest:

  • Die Basispriorität der Aufgabe, die in der Registrierung festgelegt wird.
  • Die relative Threadpriorität, die zur Laufzeit festgelegt wird, indem AvSetMmThreadPriority-aufgerufen wird.
  • Verschiedene Laufzeitmerkmale, z. B. ob sich die Anwendung im Vordergrund befindet und wie viel CPU-Zeit von den Threads in jeder MMCSS-Klasse verbraucht wird.

Eine Anwendung kann eine Arbeitswarteschlange mit MMCSS registrieren, indem MFBeginRegisterWorkQueueWithMMCSSaufgerufen wird. Diese Funktion verwendet eine Arbeitswarteschlangen-ID, eine MMCSS-Klasse (Aufgabenname) und den MMCSS-Aufgabenbezeichner. Intern ruft sie AvSetMmThreadCharacteristics mit dem Aufgabennamen und der Aufgaben-ID auf. Nachdem eine Arbeitswarteschlange bei MMCSS registriert wurde, können Sie die Klassen- und Aufgaben-ID abrufen, indem Sie MFGetWorkQueueMMCSSClass und MFGetWorkQueueMMSTaskIdaufrufen.

Die Mediensitzung bietet über die IMFWorkQueueServices Schnittstelle einen etwas höheren Zugriff auf diese APIs. Diese Schnittstelle stellt zwei primäre Methoden bereit:

Methode Beschreibung
BeginRegisterPlatformWorkQueueWithMMCSS- Registriert eine Arbeitswarteschlange mit einer MMCSS-Aufgabe. Diese Methode ist im Wesentlichen ein dünner Wrapper um MFBeginRegisterWorkQueueWithMMCSS, aber Sie können den Wert MFASYNC_CALLBACK_QUEUE_ALL übergeben, um alle Plattformarbeitswarteschlangen gleichzeitig zu registrieren.
BeginRegisterTopologyWorkQueuesWithMMCSS Registriert eine Verzweigung der Topologie mit einer Arbeitswarteschlange.

 

Gehen Sie wie folgt vor, um einen Topologiezweig zu registrieren.

  1. Legen Sie das attribut MF_TOPONODE_WORKQUEUE_ID für den Quellknoten für die Verzweigung fest. Verwenden Sie einen beliebigen anwendungsdefinierten Wert.
  2. Legen Sie optional den MF_TOPONODE_WORKQUEUE_MMCSS_CLASS fest, um die Arbeitswarteschlange mit einer MMCSS-Aufgabe zu verbinden.
  3. Rufen Sie BeginRegisterTopologyWorkQueuesWithMMCSS- für die aufgelöste Topologie auf.

Die Mediensitzung weist eine neue Arbeitswarteschlange für jeden eindeutigen Wert von MF_TOPONODE_WORKQUEUE_IDzu. Für jede Topologieverzweigung werden asynchrone Pipelinevorgänge für die Arbeitswarteschlange ausgeführt, die der Verzweigung zugewiesen ist.

IMFRealTimeClient

Die IMFRealTimeClient Schnittstelle ist für Pipelinekomponenten vorgesehen, die entweder eigene Threads erstellen oder Arbeitswarteschlangen für asynchrone Vorgänge verwenden. Die Mediensitzung verwendet diese Schnittstelle, um die Pipelinekomponente über das richtige Verhalten zu benachrichtigen:

  • Wenn die Pipelinekomponente einen Workerthread erstellt, benachrichtigt die IMFRealTimeClient::RegisterThreads- Methode die Komponente, zu der MMCSS-Klasse verknüpft werden soll.
  • Wenn die Pipelinekomponente eine Arbeitswarteschlange verwendet, teilt die IMFRealTimeClient::SetWorkQueue Methode der Komponente mit, welche Arbeitswarteschlange verwendet werden soll.

In der Regel verwendet eine Pipelinekomponente entweder einen Thread oder eine Arbeitswarteschlange, um asynchrone Aufgaben auszuführen, jedoch nicht beide.

Verbesserungen bei Windows 8

Multithread-Arbeitswarteschlangen

In Windows 8 unterstützt Media Foundation eine neue Art von Arbeitswarteschlange namens Multithread-Warteschlange. Eine Multithreadwarteschlange verwendet einen Systemthreadpool, um Arbeitsaufgaben zu verteilen. Die Multithreadwarteschlange skaliert besser als die vorherigen Singlethread-Warteschlangen. Zum Beispiel

  • Mehrere Komponenten können eine Multithreadwarteschlange gemeinsam nutzen, ohne eine andere zu blockieren, sodass weniger Threads erstellt werden müssen.

  • Arbeitsaufgaben sind optimiert, um Kontextwechsel zu vermeiden, wenn bereits ein Ereignis festgelegt ist. Dies ist effizienter als das Erstellen eigener Threads, um auf Ereignisse zu warten.

Bei verwendung von IMFRealTimeClientExsollten Anwendungen das Drehen von Threads vermeiden und stattdessen die Arbeitswarteschlangen verwenden. Zu diesem Zweck sollten Anwendungen SetWorkQueueEx- implementieren und nicht RegisterThreads und UnregisterThreads-verwenden.

Wenn die Media Foundation-Plattform initialisiert wird, wird eine Multithreadwarteschlange mit dem Bezeichner MFASYNC_CALLBACK_QUEUE_MULTITHREADEDerstellt.

Eine Multithreadwarteschlange serialisiert keine Arbeitsaufgaben. Wenn ein Thread aus dem Threadpool verfügbar wird, wird die nächste Arbeitsaufgabe in der Warteschlange verteilt. Der Aufrufer muss sicherstellen, dass die Arbeit ordnungsgemäß serialisiert ist. Um dies zu vereinfachen, definiert Media Foundation eine serielle Arbeitswarteschlange. Eine serielle Warteschlange umschließt eine andere Arbeitswarteschlange, garantiert jedoch die vollständig serialisierte Ausführung. Das nächste Element in der Warteschlange wird erst verteilt, wenn das vorherige Element abgeschlossen ist.

Der folgende Code erstellt eine Serialisierungswarteschlange über die Multithread-Warteschlange der Plattform.

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

Mehrere serielle Warteschlangen können dieselbe Multithread-Warteschlange umschließen. Die seriellen Warteschlangen verwenden dann denselben Threadpool, und die serialisierte Ausführung wird in jeder Warteschlange erzwungen.

Die Standardarbeitswarteschlangen, die vor Windows 8 vorhanden waren, werden jetzt als serielle Arbeitswarteschlangen implementiert, die die Multithreadwarteschlange der Plattform umschließen. Diese Änderung behält die Abwärtskompatibilität bei.

Arbeitswarteschlangen für freigegebene Aufgaben

Um mit dem Kernel-Scheduler ordnungsgemäß zu arbeiten, sollte für jede mmCSS-Aufgabe, die Sie verwenden, eine Multithreadarbeitswarteschlange vorhanden sein. Die Media Foundation-Plattform weist diese nach Bedarf bis zu einer pro MMCSS-Aufgabe pro Prozess zu. Um die freigegebene Arbeitswarteschlange für eine bestimmte MMCSS-Aufgabe abzurufen, rufen Sie MFLockSharedWorkQueue auf, und geben Sie den Aufgabennamen an. Die Funktion sucht den Aufgabennamen in einer Tabelle. Wenn für diesen Vorgang noch keine Arbeitswarteschlange vorhanden ist, weist die Funktion eine neue MT-Arbeitswarteschlange zu und verknüpft sie sofort mit der MMCSS-Aufgabe. Wenn für diesen Vorgang bereits eine Arbeitswarteschlange vorhanden ist, gibt die Funktion den Bezeichner der vorhandenen Arbeitswarteschlange zurück.

Warteschleife

Die Warteschleife ist eine spezielle Plattformarbeitswarteschlange, die darauf wartet, dass Ereignisse signalisiert werden. Wenn eine Komponente darauf warten muss, dass ein Ereignis signalisiert wird, kann sie die Warteschleife verwenden, anstatt einen Workerthread zu erstellen, um auf das Ereignis zu warten.

Rufen Sie MFPutWaitingWorkItem-auf, um die Warteschleife zu verwenden. Zu den Parametern gehören das Ereignishandle und ein IMFAsyncResult Zeiger. Wenn das Ereignis signalisiert wird, ruft die Warteschleife Ihren Rückruf auf. Es gibt eine einzige Plattformwarteschleife; Anwendungen können keine eigenen Warteschleifen erstellen.

Verbesserungen der MMCSS-Unterstützung

Die folgenden neuen Media Foundation-Plattformfunktionen beziehen sich auf MMCSS.

Funktion Beschreibung
MFBeginRegisterWorkQueueWithMMCSSEx Registriert eine Arbeitswarteschlange mit MMCSS. Diese Funktion enthält einen Parameter zum Angeben der relativen Threadpriorität. Intern wird dieser Wert in einen Aufruf von AvSetMmThreadPriorityübersetzt.
MFGetWorkQueueMMCSSPriority Fragt die Priorität einer Arbeitswarteschlange ab.
MFRegisterPlatformWithMMCSS- Registriert alle Plattformarbeitswarteschlangen mit einer MMCSS-Aufgabe. Diese Funktion ähnelt der IMFWorkQueueServices::BeginRegisterPlatformWorkQueueWithMMCSS--Methode, kann jedoch verwendet werden, ohne eine Instanz der Mediensitzung zu erstellen. Darüber hinaus enthält die Funktion einen Parameter zum Angeben der Basisthreadpriorität.

 

Anwendungen, die die Mediensitzung verwenden, sollten das MF_TOPONODE_WORKQUEUE_MMCSS_CLASS Attribut auf "Audio" für die Audiorendering-Verzweigung festlegen. Legen Sie das Attribut auf "Wiedergabe" für den Videorenderingzweig fest.

IMFRealTimeClientEx

Die IMFRealTimeClientEx Schnittstelle, die IMFRealTimeClient ersetzt, für Pipelinekomponenten, die asynchrone Vorgänge ausführen.

Methode Beschreibung
RegisterThreadsEx- Benachrichtigt die Komponente, seine Threads mit MMCSS zu registrieren. Diese Methode entspricht IMFRealTimeClient::RegisterThreads, fügt jedoch einen Parameter für die Basisthreadpriorität hinzu.
SetWorkQueueEx- Benachrichtigt die Komponente, eine bestimmte Arbeitswarteschlange zu verwenden. Diese Methode entspricht IMFReadTimeClient::SetWorkQueue, fügt jedoch einen Parameter für die Arbeitsaufgabenpriorität hinzu.
Aufheben der RegistrierungThreads- Benachrichtigt die Komponente, die Registrierung der Threads von MMCSS aufzuheben. Diese Methode ist identisch mit der IMFRealTimeClient::UnregisterThreads Methode.

 

Pipelinekomponenten sollten Arbeitswarteschlangen verwenden und aus den folgenden Gründen keine Arbeitsthreads erstellen:

  • Arbeitswarteschlangen werden besser skaliert, da sie die BS-Threadpools verwenden.
  • Die Plattform behandelt die Details zum Registrieren von Arbeitswarteschlangen bei MMCSS.
  • Ein Workerthread kann leicht zu einem Deadlock führen, der schwer zu debuggen ist.

Erwägen Sie außerdem die Verwendung der Serialisierungswarteschlange, wenn Sie Ihre asynchronen Vorgänge serialisieren müssen.

Topologiezweige

Wenn das attribut MF_TOPONODE_WORKQUEUE_MMCSS_CLASS einen Topologiezweig mit MMCSS registriert, verwendet die Mediensitzung in Windows 8 die freigegebenen MT-Arbeitswarteschlangen. In früheren Versionen von Windows hat die Mediensitzung eine neue Arbeitswarteschlange zugewiesen.

Für die Registrierung eines Topologiezweigs mit MMCSS sind zwei neue Attribute definiert.

Attribut Beschreibung
MF_TOPONODE_WORKQUEUE_MMCSS_PRIORITY Gibt die Basisthreadpriorität an.
MF_TOPONODE_WORKQUEUE_ITEM_PRIORITY Gibt die Arbeitsaufgabenpriorität an.

 

Empfehlungen

  • Anwendungen, die die Mediensitzung verwenden, sollten MF_TOPONODE_WORKQUEUE_MMCSS_CLASS auf "Audio" für die Audiorendering-Verzweigung und "Wiedergabe" für den Videorenderingzweig festlegen.
  • Anwendungen, die die Mediensitzung verwenden, sollten IMFWorkQueueServices::BeginRegisterTopologyWorkQueuesWithMMCSS in der Topologie aufrufen.
  • Für Pipelinekomponenten werden Arbeitswarteschlangen anstelle von Arbeitsthreads empfohlen. Wenn die Komponente arbeitswarteschlangen oder Arbeitsthreads verwendet, implementieren Sie IMFRealTimeClientEx.
  • Erstellen Sie keine privaten Arbeitswarteschlangen, da dies den Zweck der Plattformarbeitswarteschlangen besiegt. Verwenden Sie entweder die Plattform-Multithread-Warteschlange oder eine serielle Warteschlange, die die Multithread-Warteschlange der Plattform umschließt.
  • Wenn Sie asynchrone Vorgänge serialisieren müssen, verwenden Sie eine serielle Warteschlange.

Zusammenfassung

Die folgenden Media Foundation-Plattform-APIs, die sich auf Threads und Arbeitswarteschlangen beziehen, sind neu für Windows 8.

Arbeitswarteschlangen