Mejoras en la cola de trabajo y subprocesos

En este tema se describen las mejoras de Windows 8 para colas de trabajo y subprocesos en la plataforma Microsoft Media Foundation.

Comportamiento de Windows 7

En esta sección se resume el comportamiento de las colas de trabajo de Media Foundation en Windows 7.

Colas de trabajo

La plataforma media Foundation crea varias colas de trabajo estándar. Solo dos se documentan como para uso general de la aplicación:

  • MFASYNC_CALLBACK_QUEUE_STANDARD
  • MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION

Una aplicación o componente puede asignar nuevas colas de trabajo llamando a MFAllocateWorkQueue o MFAllocateWorkQueueEx. La función MFAllocateWorkQueueEx define dos tipos de cola de trabajo:

  • MF_STANDARD_WORKQUEUE crea una cola de trabajo sin un bucle de mensajes.
  • MF_WINDOW_WORKQUEUE crea una cola de trabajo con un bucle de mensajes.

Para poner en cola un elemento de trabajo, llame a MFPutWorkItem o MFPutWorkItemEx. La plataforma ejecuta el elemento de trabajo invocando la implementación proporcionada por el autor de la llamada de IMFAsyncCallback. En Windows 7 y versiones anteriores, la plataforma crea un subproceso por cola de trabajo.

Compatibilidad con MMCSS

El Servicio de programador de clases multimedia (MMCSS) administra las prioridades de subprocesos para que las aplicaciones multimedia obtengan segmentos regulares de tiempo de CPU, sin denegar los recursos de CPU a aplicaciones de prioridad inferior. MMCSS define un conjunto de tareas que tienen perfiles de uso de CPU diferentes. Cuando un subproceso combina una tarea MMCSS, MMCSS establece la prioridad del subproceso en función de varios factores:

  • Prioridad base de la tarea, que se establece en el Registro.
  • Prioridad relativa del subproceso, que se establece en tiempo de ejecución mediante una llamada a AvSetMmThreadPriority.
  • Varias características en tiempo de ejecución, como si la aplicación está en primer plano y cuánto tiempo de CPU consumen los subprocesos de cada clase MMCSS.

Una aplicación puede registrar una cola de trabajo con MMCSS llamando a MFBeginRegisterWorkQueueWithMMCSS. Esta función toma un identificador de cola de trabajo, una clase MMCSS (nombre de tarea) y el identificador de tarea MMCSS. Internamente, llama a AvSetMmThreadCharacteristics con el nombre de tarea y el identificador de tarea. Una vez registrada una cola de trabajo con MMCSS, puede obtener el identificador de clase y tarea llamando a MFGetWorkQueueMMCSSClass y MFGetWorkQueueMMCSSTaskId.

La sesión multimedia proporciona acceso de nivel superior a estas API a través de la interfaz IMFWorkQueueServices . Esta interfaz proporciona dos métodos principales:

Método Descripción
BeginRegisterPlatformWorkQueueWithMMCSS Registra una cola de trabajo con una tarea MMCSS. Este método es básicamente un contenedor fino alrededor de MFBeginRegisterWorkQueueWithMMCSS, pero puede pasar el valor MFASYNC_CALLBACK_QUEUE_ALL para registrar todas las colas de trabajo de la plataforma a la vez.
BeginRegisterTopologyWorkQueuesWithMMCSS Registra una rama de la topología con una cola de trabajo.

 

Para registrar una rama de topología, haga lo siguiente.

  1. Establezca el atributo MF_TOPONODE_WORKQUEUE_ID en el nodo de origen de la rama. Use cualquier valor definido por la aplicación.
  2. Opcionalmente, establezca la MF_TOPONODE_WORKQUEUE_MMCSS_CLASS para unir la cola de trabajo a una tarea MMCSS.
  3. Llame a BeginRegisterTopologyWorkQueuesWithMMCSS en la topología resuelta.

La sesión multimedia asigna una nueva cola de trabajo para cada valor único de MF_TOPONODE_WORKQUEUE_ID. Para cada rama de topología, las operaciones de canalización asincrónicas se realizan en la cola de trabajo que se asigna a la rama.

IMFRealTimeClient

La interfaz IMFRealTimeClient está pensada para componentes de canalización que crean sus propios subprocesos o usan colas de trabajo para operaciones asincrónicas. La sesión multimedia usa esta interfaz para notificar al componente de canalización el comportamiento correcto, como se indica a continuación:

Normalmente, un componente de canalización usa un subproceso o una cola de trabajo para realizar tareas asincrónicas, pero no ambas.

Mejoras de Windows 8

Colas de trabajo multiproceso

En Windows 8, Media Foundation admite un nuevo tipo de cola de trabajo denominado cola multiproceso. Una cola multiproceso usa un grupo de subprocesos del sistema para enviar elementos de trabajo. La cola multiproceso se escala mejor que las colas de un solo subproceso anteriores. Por ejemplo,

  • Varios componentes pueden compartir una cola multiproceso sin bloquearse entre sí, lo que requiere la creación de menos subprocesos.

  • Los elementos de trabajo están optimizados para evitar cambios de contexto si ya se ha establecido un evento. Esto es más eficaz que crear sus propios subprocesos para esperar eventos.

Al usar IMFRealTimeClientEx, las aplicaciones deben evitar la puesta en marcha de subprocesos y, en su lugar, deben usar las colas de trabajo. Para ello, las aplicaciones deben implementar SetWorkQueueEx y no usar RegisterThreads y UnregisterThreads.

Cuando se inicializa la plataforma media Foundation, crea una cola multiproceso con el identificador MFASYNC_CALLBACK_QUEUE_MULTITHREADED.

Una cola multiproceso no serializa elementos de trabajo. Cada vez que un subproceso del grupo de subprocesos esté disponible, se envía el siguiente elemento de trabajo de la cola. El autor de la llamada debe asegurarse de que el trabajo se serializa correctamente. Para facilitar esta tarea, Media Foundation define una cola de trabajo serie. Una cola serie encapsula otra cola de trabajo, pero garantiza una ejecución totalmente serializada. El siguiente elemento de la cola no se envía hasta que se completa el elemento anterior.

El código siguiente crea una cola de serializador a través de la cola multiproceso de la plataforma.

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

Más de una cola serie puede encapsular la misma cola multiproceso. A continuación, las colas serie comparten el mismo grupo de subprocesos y la ejecución serializada se aplica dentro de cada cola.

Las colas de trabajo estándar que existían antes de Windows 8 ahora se implementan como colas de trabajo serie que encapsulan la cola multiproceso de la plataforma. Este cambio conserva la compatibilidad con versiones anteriores.

Colas de trabajo de tareas compartidas

Para trabajar correctamente con el programador de kernel, debe haber una cola de trabajo multiproceso para cada tarea MMCSS que use. La plataforma media Foundation asigna estos elementos según sea necesario, hasta uno por tarea MMCSS, por proceso. Para obtener la cola de trabajo compartida para una tarea MMCSS determinada, llame a MFLockSharedWorkQueue y especifique el nombre de la tarea. La función busca el nombre de la tarea en una tabla. Si aún no existe una cola de trabajo para esta tarea, la función asigna una nueva cola de trabajo mt y la une inmediatamente a la tarea MMCSS. Si ya existe una cola de trabajo para esa tarea, la función devuelve el identificador de la cola de trabajo existente.

Cola de espera

La cola de espera es una cola de trabajo de plataforma especial que espera a que se indiquen eventos. Si un componente debe esperar a que se indique un evento, puede usar la cola de espera en lugar de crear un subproceso de trabajo para esperar en el evento.

Para usar la cola de espera, llame a MFPutWaitingWorkItem. Los parámetros incluyen el identificador de eventos y un puntero IMFAsyncResult . Cuando se señala el evento, la cola de espera invoca la devolución de llamada. Hay una cola de espera de plataforma única; las aplicaciones no pueden crear sus propias colas de espera.

Mejoras en la compatibilidad con MMCSS

Las siguientes nuevas funciones de plataforma de Media Foundation se relacionan con MMCSS.

Función Descripción
MFBeginRegisterWorkQueueWithMMCSSEx Registra una cola de trabajo con MMCSS. Esta función incluye un parámetro para especificar la prioridad relativa del subproceso. Internamente, este valor se traduce en una llamada a AvSetMmThreadPriority.
MFGetWorkQueueMMCSSPriority Consulta la prioridad de una cola de trabajo.
MFRegisterPlatformWithMMCSS Registra todas las colas de trabajo de la plataforma con una tarea MMCSS. Esta función es similar al método IMFWorkQueueServices::BeginRegisterPlatformWorkQueueWithMMCSS , pero se puede usar sin crear una instancia de la sesión multimedia. Además, la función incluye un parámetro para especificar la prioridad del subproceso base.

 

Las aplicaciones que usan la sesión multimedia deben establecer el atributo MF_TOPONODE_WORKQUEUE_MMCSS_CLASS en "Audio" para la rama de representación de audio. Establezca el atributo en "Playback" (Reproducción) para la rama de representación de vídeo.

IMFRealTimeClientEx

La interfaz IMFRealTimeClientEx reemplaza a IMFRealTimeClient , para los componentes de canalización que realizan operaciones asincrónicas.

Método Descripción
RegisterThreadsEx Notifica al componente que registre sus subprocesos con MMCSS. Este método es equivalente a IMFRealTimeClient::RegisterThreads, pero agrega un parámetro para la prioridad del subproceso base.
SetWorkQueueEx Notifica al componente que use una cola de trabajo específica. Este método es equivalente a IMFReadTimeClient::SetWorkQueue, pero agrega un parámetro para la prioridad del elemento de trabajo.
Anular el registroThreads Notifica al componente que anule el registro de sus subprocesos de MMCSS. Este método es idéntico al método IMFRealTimeClient::UnregisterThreads .

 

Los componentes de canalización deben usar colas de trabajo y no deben crear subprocesos de trabajo por los siguientes motivos:

  • Las colas de trabajo se escalan mejor, ya que usan los grupos de subprocesos del sistema operativo.
  • La plataforma controla los detalles del registro de colas de trabajo con MMCSS.
  • Un subproceso de trabajo puede provocar fácilmente un interbloqueo difícil de depurar.

Además, considere la posibilidad de usar la cola de trabajo del serializador si necesita serializar las operaciones asincrónicas.

Ramas de topología

Si el atributo MF_TOPONODE_WORKQUEUE_MMCSS_CLASS registra una rama de topología con MMCSS, en Windows 8 la sesión multimedia usa las colas de trabajo de MT compartidas. En versiones anteriores de Windows, la sesión multimedia asignó una nueva cola de trabajo.

Se definen dos nuevos atributos para registrar una rama de topología con MMCSS.

Atributo Descripción
MF_TOPONODE_WORKQUEUE_MMCSS_PRIORITY Especifica la prioridad del subproceso base.
MF_TOPONODE_WORKQUEUE_ITEM_PRIORITY Especifica la prioridad del elemento de trabajo.

 

Recomendaciones

  • Las aplicaciones que usan la sesión multimedia deben establecer MF_TOPONODE_WORKQUEUE_MMCSS_CLASS en "Audio" para la rama de representación de audio y "Reproducción" para la rama de representación de vídeo.
  • Las aplicaciones que usan la sesión multimedia deben llamar a IMFWorkQueueServices::BeginRegisterTopologyWorkQueuesWithMMCSS en la topología.
  • En el caso de los componentes de canalización, se recomiendan las colas de trabajo en lugar de los subprocesos de trabajo. Si el componente usa colas de trabajo o subprocesos de trabajo, implemente IMFRealTimeClientEx.
  • No cree colas de trabajo privadas, ya que esto anula el propósito de las colas de trabajo de la plataforma. Use la cola multiproceso de la plataforma o una cola serie que encapsula la cola multiproceso de la plataforma.
  • Si necesita serializar operaciones asincrónicas, use una cola serie.

Resumen

Las siguientes API de plataforma de Media Foundation relacionadas con subprocesos y colas de trabajo son nuevas para Windows 8.

Colas de trabajo