Verbesserungen bei Arbeitswarteschlangen und Threading
In diesem Thema werden Verbesserungen Windows 8 Arbeitswarteschlangen und Threading in der Microsoft Media Foundation beschrieben.
Windows 7-Verhalten
In diesem Abschnitt wird das Verhalten Media Foundation Arbeitswarteschlangen in Windows 7 zusammengefasst.
Arbeitswarteschlangen
Die Media Foundation-Plattform erstellt mehrere Standardarbeitswarteschlangen. Nur zwei werden als für die allgemeine Anwendungsnutzung dokumentiert:
- MFASYNC _ CALLBACK _ QUEUE _ STANDARD
- _LONG-FUNKTION DER MFASYNC-RÜCKRUFWARTESCHLANGE _ _ _
Eine Anwendung oder Komponente kann neue Arbeitswarteschlangen zuordnen, indem sie MFAllocateWorkQueue oder MFAllocateWorkQueueEx aufruft. Die MFAllocateWorkQueueEx-Funktion definiert zwei Arten von Arbeitswarteschlangen:
- MF _ STANDARD _ WORKQUEUE erstellt eine Arbeitswarteschlange ohne Nachrichtenschleife.
- MF _ WINDOW _ WORKQUEUE erstellt eine Arbeitswarteschlange mit einer Nachrichtenschleife.
Um ein Arbeitselement in die Warteschlange zu stellen, rufen Sie MFPutWorkItem oder MFPutWorkItemEx auf. Die Plattform führt das Arbeitselement aus, indem die vom Aufrufer bereitgestellte Implementierung vonASYNCCallback aufgerufen wird. In Windows 7 und früher erstellt die Plattform einen Thread pro Arbeitswarteschlange.
MMCSS-Unterstützung
Der Multimedia Class Scheduler Service (MMCSS) verwaltet Threadprioritäten, sodass Multimediaanwendungen reguläre Slices 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 einer MMCSS-Aufgabe beitritt, legt MMCSS die Priorität des Threads basierend auf mehreren Faktoren fest:
- Die Basispriorität der Aufgabe, die in der Registrierung festgelegt ist.
- Die relative Threadpriorität, die zur Laufzeit durch Aufrufen von AvSetMmThreadPriority festgelegt 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 bei MMCSS registrieren, indem sie MFBeginRegisterWorkQueueWithMMCSS aufruft. Diese Funktion verwendet eine Arbeitswarteschlangen-ID, eine MMCSS-Klasse (Aufgabenname) und den MMCSS-Taskbezeichner. Intern wird AvSetMmThreadCharacteristics mit dem Tasknamen und der Aufgaben-ID aufruft. Nachdem eine Arbeitswarteschlange bei MMCSS registriert wurde, können Sie die Klassen- und Aufgaben-ID durch Aufrufen von MFGetWorkQueueMMCSSClass und MFGetWorkQueueMMCSSTaskId erhalten.
Die Mediensitzung bietet über die BENUTZEROBERFLÄCHEWorkQueueServices-Schnittstelle zugriff auf diese APIs auf höherer Ebene. Diese Schnittstelle stellt zwei primäre Methoden bereit:
| Methode | Beschreibung |
|---|---|
| BeginRegisterPlatformWorkQueueWithMMCSS | Registriert eine Arbeitswarteschlange bei einem MMCSS-Task. Diese Methode ist im Wesentlichen ein schlanker Wrapper um MFBeginRegisterWorkQueueWithMMCSS.Sie können jedoch den Wert MFASYNC _ CALLBACK _ QUEUE _ ALL übergeben, um alle Plattformarbeitswarteschlangen gleichzeitig zu registrieren. |
| BeginRegisterTopologyWorkQueuesWithMMCSS | Registriert einen Branch der Topologie bei einer Arbeitswarteschlange. |
Gehen Sie wie folgt vor, um einen Topologiezweig zu registrieren.
- Legen Sie das _ MF-ATTRIBUT TOPONODE _ WORKQUEUE _ ID auf dem Quellknoten für den Branch fest. Verwenden Sie einen beliebigen anwendungsdefinierten Wert.
- Legen Sie optional die MF _ TOPONODE _ WORKQUEUE _ MMCSS-KLASSE _ fest, um die Arbeitswarteschlange mit einem MMCSS-Task zu verbinden.
- Rufen Sie BeginRegisterTopologyWorkQueuesWithMMCSS für die aufgelöste Topologie auf.
Die Mediensitzung ordnet jedem eindeutigen Wert der MF _ TOPONODE _ WORKQUEUE-ID eine neue Arbeitswarteschlange _ zu. Für jeden Topologiezweig werden asynchrone Pipelinevorgänge für die Arbeitswarteschlange ausgeführt, die dem Branch zugewiesen ist.
VERALTENRealTimeClient
Die ASYNCHRONOUSRealTimeClient-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 wie folgt über das richtige Verhalten zu benachrichtigen:
- Wenn die Pipelinekomponente einen Arbeitsthread erstellt, benachrichtigt die METHODE DURCHTREALTimeClient::RegisterThreads die Komponente, der die MMCSS-Klasse beitreten soll.
- Wenn die Pipelinekomponente eine Arbeitswarteschlange verwendet, teilt die METHODE MITREALTimeClient::SetWorkQueue 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, aber nicht beide.
Windows 8 Verbesserungen
Multithreadarbeitswarteschlangen
In Windows 8 unterstützt Media Foundation eine neue Art von Arbeitswarteschlange, die als Multithreadwarteschlange bezeichnet wird. Eine Multithreadwarteschlange verwendet einen Systemthreadpool, um Arbeitselemente zu senden. Die Multithreadwarteschlange wird besser skaliert als die vorherigen Singlethread-Warteschlangen. Beispiel:
Mehrere Komponenten können eine Multithreadwarteschlange gemeinsam verwenden, ohne einander zu blockieren, was die Erstellung von weniger Threads erfordert.
Arbeitselemente 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.
Wenn SIE DENTREALTimeClientEx verwenden,sollten Anwendungen vermeiden, Threads hoch- und stattdessen die Arbeitswarteschlangen zu verwenden. Um dies zu erreichen, 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 _ MULTITHREADED erstellt.
Eine Multithreadwarteschlange serialisiert keine Arbeitselemente. Wenn ein Thread aus dem Threadpool verfügbar wird, wird das nächste Arbeitselement in der Warteschlange gesendet. Der Aufrufer muss sicherstellen, dass die Arbeit ordnungsgemäß serialisiert wird. Um dies zu vereinfachen, Media Foundation eine serielle Arbeitswarteschlange definiert. Eine serielle Warteschlange umschließt eine andere Arbeitswarteschlange, garantiert jedoch eine vollständig serialisierte Ausführung. Das nächste Element in der Warteschlange wird erst gesendet, wenn das vorherige Element abgeschlossen ist.
Der folgende Code erstellt eine Serialisierungswarteschlange über der Plattform-Multithreadwarteschlange.
DWORD workQueueID;
hr = MFAllocateSerialWorkQueue(MFASYNC_CALLBACK_QUEUE_MULTITHREADED, &workQueueID);
Mehrere serielle Warteschlangen können dieselbe Multithreadwarteschlange umschließen. Die seriellen Warteschlangen nutzen dann den gleichen Threadpool, und die serialisierte Ausführung wird innerhalb jeder Warteschlange erzwungen.
Die Standardarbeitswarteschlangen, die vor Windows 8 vorhanden waren, werden jetzt als serielle Arbeitswarteschlangen implementiert, die die Plattform-Multithreadwarteschlange umschließen. Diese Änderung behält die Abwärtskompatibilität bei.
Arbeitswarteschlangen für freigegebene Aufgaben
Um ordnungsgemäß mit dem Kernelplaner zu arbeiten, sollte es eine Multithreadarbeitswarteschlange für jeden mmcss-Task geben, den Sie verwenden. Die Media Foundation-Plattform ordnet diese nach Bedarf zu, bis zu einer pro MMCSS-Aufgabe und pro Prozess. Um die freigegebene Arbeitswarteschlange für einen bestimmten MMCSS-Task zu erhalten, rufen Sie MFLockSharedWorkQueue auf, und geben Sie den Aufgabennamen an. Die Funktion sucht den Aufgabennamen in einer Tabelle. Wenn für diese Aufgabe noch keine Arbeitswarteschlange vorhanden ist, ordnet die Funktion eine neue MT-Arbeitswarteschlange zu und verbindet sie sofort mit der MMCSS-Aufgabe. Wenn bereits eine Arbeitswarteschlange für diese Aufgabe vorhanden ist, gibt die Funktion den Bezeichner der vorhandenen Arbeitswarteschlange zurück.
Wartewarteschlange
Die Wartewarteschlange ist eine spezielle Plattformarbeitswarteschlange, die darauf wartet, dass Ereignisse signalisiert werden. Wenn eine Komponente warten muss, bis ein Ereignis signalisiert wird, kann sie die Wartewarteschlange verwenden, anstatt einen Arbeitsthread zum Warten auf das Ereignis zu erstellen.
Um die Wartewarteschlange zu verwenden, rufen Sie MFPutWaitingWorkItem auf. Die Parameter enthalten das Ereignishand handle und einenASYNCAsyncResult-Zeiger. Wenn das Ereignis signalisiert wird, ruft die Wartewarteschlange Ihren Rückruf auf. Es gibt eine einzelne Plattformwartewarteschlange. -Anwendungen können keine eigenen Wartewarteschlangen erstellen.
Verbesserungen an der MMCSS-Unterstützung
Die folgenden neuen Media Foundation Plattformfunktionen beziehen sich auf MMCSS.
| Funktion | Beschreibung |
|---|---|
| MFBeginRegisterWorkQueueWithMMCSSEx | Registriert eine Arbeitswarteschlange bei 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 bei einem MMCSS-Task. Diese Funktion ähnelt der METHODE VONWORKQueueServices::BeginRegisterPlatformWorkQueueWithMMCSS, kann jedoch ohne Erstellung einer Instanz der Mediensitzung verwendet werden. 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 für den Audiorendering-Branch auf "Audio" festlegen. Legen Sie das -Attribut für den Videorendering-Branch auf "Playback" fest.
VERALTENRealTimeClientEx
Die ZU ersetzende INTERFACESRealTimeClientEx-Schnittstelle ersetzt DENREALRealTimeClient für Pipelinekomponenten, die asynchrone Vorgänge ausführen.
| Methode | Beschreibung |
|---|---|
| RegisterThreadsEx | Benachrichtigt die Komponente, ihre Threads bei MMCSS zu registrieren. Diese Methode entspricht DEM PARAMETERSRealTimeClient::RegisterThreads,fügt jedoch einen Parameter für die Basisthreadpriorität hinzu. |
| SetWorkQueueEx | Benachrichtigt die Komponente, eine bestimmte Arbeitswarteschlange zu verwenden. Diese Methode entspricht DEM PARAMETERSReadTimeClient::SetWorkQueue,fügt jedoch einen Parameter für die Arbeitselementpriorität hinzu. |
| UnregisterThreads | Benachrichtigt die Komponente, die Registrierung ihrer Threads bei MMCSS zu aufheben. Diese Methode ist identisch mit der IDENTICALRealTimeClient::UnregisterThreads-Methode. |
Pipelinekomponenten sollten aus den folgenden Gründen Arbeitswarteschlangen verwenden und keine Arbeitsthreads erstellen:
- Arbeitswarteschlangen werden besser skaliert, da sie die Betriebssystemthreadpools verwenden.
- Die Plattform verarbeitet die Details zum Registrieren von Arbeitswarteschlangen bei MMCSS.
- Ein Arbeitsthread kann leicht einen Deadlock verursachen, der schwer zu debuggen ist.
Erwägen Sie außerdem die Verwendung der Arbeitswarteschlange des Serialisierungsprogramms, wenn Sie Ihre asynchronen Vorgänge serialisieren müssen.
Topologiebranches
Wenn das MF _ TOPONODE _ WORKQUEUE _ MMCSS _ CLASS-Attribut einen Topologiezweig bei MMCSS registriert, verwendet die Mediensitzung in Windows 8 die freigegebenen MT-Arbeitswarteschlangen. In früheren Versionen von Windows hat die Mediensitzung eine neue Arbeitswarteschlange zugeordnet.
Für die Registrierung eines Topologiezweigs bei MMCSS werden zwei neue Attribute definiert.
| attribute | Beschreibung |
|---|---|
| MF _ TOPONODE _ WORKQUEUE _ MMCSS _ PRIORITY | Gibt die Basisthreadpriorität an. |
| MF _ TOPONODE _ WORKQUEUE _ ITEM _ PRIORITY | Gibt die Arbeitselementpriorität an. |
Empfehlungen
- Anwendungen, die die Mediensitzung verwenden, sollten MF _ TOPONODE _ WORKQUEUE _ MMCSS _ CLASS für den Audiorendering-Branch auf "Audio" und für den Videorendering-Branch auf "Playback" festlegen.
- Anwendungen, die die Mediensitzung verwenden, sollten IN DER Topologie DEN AUFRUF VONWORKQUEUESERVICES::BeginRegisterTopologyWorkQueuesWithMMCSS aufrufen.
- Für Pipelinekomponenten werden Arbeitswarteschlangen anstelle von Arbeitsthreads empfohlen. Wenn die Komponente entweder Arbeitswarteschlangen oder Arbeitsthreads verwendet, implementieren Sie DIE WarteschlangeNREALRealTimeClientEx.
- Erstellen Sie keine privaten Arbeitswarteschlangen, da dies den Zweck der Plattformarbeitswarteschlangen vereiteelt. Verwenden Sie entweder die Plattform-Multithreadwarteschlange oder eine serielle Warteschlange, die die Plattform-Multithreadwarteschlange 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 für Windows 8 neu.
- MF _ TOPONODE _ WORKQUEUE _ ITEM _ PRIORITY
- MF _ TOPONODE _ WORKQUEUE _ MMCSS _ PRIORITY
- MFAllocateSerialWorkQueue
- MFBeginRegisterWorkQueueWithMMCSSEx
- MFGetWorkQueueMMCSSPriority
- MFPutWaitingWorkItem
- MFPutWorkItem2
- MFPutWorkItemEx2
- MFRegisterPlatformWithMMCSS
- MFUnregisterPlatformFromMMCSS
- MFLockSharedWorkQueue
- VERALTENRealTimeClientEx