Compartilhar via


Melhorias na fila de trabalho e no threading

Este tópico descreve melhorias no Windows 8 para filas de trabalho e threading na plataforma Microsoft Media Foundation.

Comportamento do Windows 7

Esta seção resume o comportamento das filas de trabalho do Media Foundation no Windows 7.

Filas de trabalho

A plataforma do Media Foundation cria várias filas de trabalho padrão. Apenas dois estão documentados como sendo para uso geral do aplicativo:

  • MFASYNC_CALLBACK_QUEUE_STANDARD
  • MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION

Um aplicativo ou componente pode alocar novas filas de trabalho chamando MFAllocateWorkQueue ou MFAllocateWorkQueueEx. A função MFAllocateWorkQueueEx define dois tipos de fila de trabalho:

  • MF_STANDARD_WORKQUEUE cria uma fila de trabalho sem um loop de mensagem.
  • MF_WINDOW_WORKQUEUE cria uma fila de trabalho com um loop de mensagem.

Para enfileirar um item de trabalho, chame MFPutWorkItem ou MFPutWorkItemEx . A plataforma executa o item de trabalho invocando a implementação fornecida pelo chamador de IMFAsyncCallback . No Windows 7 e anteriores, a plataforma cria um thread por fila de trabalho.

Suporte ao MMCSS

O MMCSS (de Serviço de Agendador de Classe Multimídia) gerencia as prioridades de thread para que os aplicativos multimídia obtenham fatias regulares de tempo de CPU, sem negar recursos de CPU a aplicativos de menor prioridade. O MMCSS define um conjunto de tarefas que têm perfis de utilização de CPU diferentes. Quando um thread une uma tarefa MMCSS, o MMCSS define a prioridade do thread com base em vários fatores:

  • A prioridade base da tarefa, que é definida no Registro.
  • A prioridade relativa do thread, que é definida em tempo de execução chamando AvSetMmThreadPriority.
  • Várias características de tempo de execução, como se o aplicativo está em primeiro plano e quanto tempo de CPU está sendo consumido pelos threads em cada classe MMCSS.

Um aplicativo pode registrar uma fila de trabalho com o MMCSS chamando MFBeginRegisterWorkQueueWithMMCSS. Essa função usa uma ID da fila de trabalho, uma classe MMCSS (nome da tarefa) e o identificador de tarefa MMCSS. Internamente, ele chama AvSetMmThreadCharacteristics com o nome da tarefa e a ID da tarefa. Depois que uma fila de trabalho é registrada com o MMCSS, você pode obter a ID de classe e tarefa chamando MFGetWorkQueueMMCSSClass e MFGetWorkQueueMMCSSTaskId.

O da Sessão de Mídia fornece acesso de nível um pouco mais alto a essas APIs, por meio da interface IMFWorkQueueServices. Essa interface fornece dois métodos primários:

Método Descrição
BeginRegisterPlatformWorkQueueWithMMCSS Registra uma fila de trabalho com uma tarefa MMCSS. Esse método é essencialmente um wrapper fino MFBeginRegisterWorkQueueWithMMCSS, mas você pode passar o valor MFASYNC_CALLBACK_QUEUE_ALL para registrar todas as filas de trabalho da plataforma de uma só vez.
BeginRegisterTopologyWorkQueuesWithMMCSS Registra um branch da topologia com uma fila de trabalho.

 

Para registrar um branch de topologia, faça o seguinte.

  1. Defina o atributo MF_TOPONODE_WORKQUEUE_ID no nó de origem do branch. Use qualquer valor definido pelo aplicativo.
  2. Opcionalmente, defina o MF_TOPONODE_WORKQUEUE_MMCSS_CLASS para ingressar na fila de trabalho para uma tarefa MMCSS.
  3. Chame BeginRegisterTopologyWorkQueuesWithMMCSS na topologia resolvida.

A Sessão de Mídia aloca uma nova fila de trabalho para cada valor exclusivo de MF_TOPONODE_WORKQUEUE_ID. Para cada branch de topologia, as operações de pipeline assíncronas são executadas na fila de trabalho atribuída ao branch.

IMFRealTimeClient

A interfaceIMFRealTimeClient destina-se a componentes de pipeline que criam seus próprios threads ou usam filas de trabalho para operações assíncronas. A Sessão de Mídia usa essa interface para notificar o componente de pipeline do comportamento correto, da seguinte maneira:

Normalmente, um componente de pipeline usa um thread ou uma fila de trabalho para executar tarefas assíncronas, mas não ambas.

Melhorias do Windows 8

Filas de trabalho multithreaded

No Windows 8, o Media Foundation dá suporte a um novo tipo de fila de trabalho chamada fila multithreaded. Uma fila multithread usa um pool de threads do sistema para expedir itens de trabalho. A fila multithread é dimensionada melhor do que as filas de thread único anteriores. Por exemplo

  • Vários componentes podem compartilhar uma fila multithreaded sem bloquear uns aos outros, exigindo a criação de menos threads.

  • Os itens de trabalho são otimizados para evitar comutadores de contexto se um evento já estiver definido. Isso é mais eficiente do que criar seus próprios threads para aguardar eventos.

Ao usar IMFRealTimeClientEx, os aplicativos devem evitar girar threads e, em vez disso, devem usar as filas de trabalho. Para fazer isso, os aplicativos devem implementar SetWorkQueueEx e não usar RegisterThreads e UnregisterThreads.

Quando a plataforma do Media Foundation é inicializada, ela cria uma fila multithreaded com o identificador MFASYNC_CALLBACK_QUEUE_MULTITHREADED.

Uma fila multithreaded não serializa itens de trabalho. Sempre que um thread do pool de threads estiver disponível, o próximo item de trabalho na fila será expedido. O chamador deve garantir que o trabalho seja serializado corretamente. Para facilitar isso, o Media Foundation define uma fila de trabalho serial . Uma fila serial encapsula outra fila de trabalho, mas garante a execução totalmente serializada. O próximo item na fila não é expedido até que o item anterior seja concluído.

O código a seguir cria uma fila de serializadores na fila multithreaded da plataforma.

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

Mais de uma fila serial pode encapsular a mesma fila multithreaded. Em seguida, as filas serial compartilham o mesmo pool de threads e a execução serializada é imposta em cada fila.

As filas de trabalho padrão que existiam antes do Windows 8 agora são implementadas como filas de trabalho serial que encapsulam a fila multithreaded da plataforma. Essa alteração preserva a compatibilidade com versões anteriores.

Filas de trabalho de tarefas compartilhadas

Para trabalhar corretamente com o agendador de kernel, deve haver uma fila de trabalho multithreaded para cada tarefa MMCSS que você usa. A plataforma do Media Foundation as aloca conforme necessário, até uma por tarefa MMCSS, por processo. Para obter a fila de trabalho compartilhada para uma tarefa MMCSS específica, chame MFLockSharedWorkQueue e especifique o nome da tarefa. A função procura o nome da tarefa em uma tabela. Se uma fila de trabalho ainda não existir para essa tarefa, a função alocará uma nova fila de trabalho mt e a unirá imediatamente à tarefa MMCSS. Se já existir uma fila de trabalho para essa tarefa, a função retornará o identificador da fila de trabalho existente.

Fila de espera

A fila de espera é uma fila de trabalho de plataforma especial que aguarda que os eventos sejam sinalizados. Se um componente precisar esperar que um evento seja sinalizado, ele poderá usar a fila de espera em vez de criar um thread de trabalho para aguardar o evento.

Para usar a fila de espera, chame MFPutWaitingWorkItem. Os parâmetros incluem o identificador de evento e um ponteiroIMFAsyncResult. Quando o evento é sinalizado, a fila de espera invoca o retorno de chamada. Há uma fila de espera de plataforma única; os aplicativos não podem criar suas próprias filas de espera.

Aprimoramentos no suporte ao MMCSS

As novas funções de plataforma do Media Foundation a seguir estão relacionadas ao MMCSS.

Função Descrição
MFBeginRegisterWorkQueueWithMMCSSEx Registra uma fila de trabalho com o MMCSS. Essa função inclui um parâmetro para especificar a prioridade relativa do thread. Internamente, esse valor é convertido em uma chamada para AvSetMmThreadPriority.
MFGetWorkQueueMMCSSPriority Consulta a prioridade de uma fila de trabalho.
MFRegisterPlatformWithMMCSS Registra todas as filas de trabalho da plataforma com uma tarefa MMCSS. Essa função é semelhante ao métodoIMFWorkQueueServices::BeginRegisterPlatformWorkQueueWithMMCSS, mas pode ser usada sem criar uma instância da Sessão de Mídia. Além disso, a função inclui um parâmetro para especificar a prioridade de thread base.

 

Os aplicativos que usam a Sessão de Mídia devem definir o atributo MF_TOPONODE_WORKQUEUE_MMCSS_CLASS como "Áudio" para o branch de renderização de áudio. Defina o atributo como "Reprodução" para o branch de renderização de vídeo.

IMFRealTimeClientEx

A interface IMFRealTimeClientEx para substituir IMFRealTimeClient, para componentes de pipeline que executam operações assíncronas.

Método Descrição
RegisterThreadsEx Notifica o componente para registrar seus threads com o MMCSS. Esse método é equivalente a IMFRealTimeClient::RegisterThreads, mas adiciona um parâmetro para a prioridade de thread base.
SetWorkQueueEx Notifica o componente para usar uma fila de trabalho específica. Esse método é equivalente a IMFReadTimeClient::SetWorkQueue, mas adiciona um parâmetro para a prioridade do item de trabalho.
unregisterThreads Notifica o componente para cancelar o registro de seus threads do MMCSS. Esse método é idêntico ao métodoIMFRealTimeClient::UnregisterThreads.

 

Os componentes de pipeline devem usar filas de trabalho e não devem criar threads de trabalho, pelos seguintes motivos:

  • As filas de trabalho são mais dimensionadas, pois usam os pools de threads do sistema operacional.
  • A plataforma lida com os detalhes do registro de filas de trabalho com o MMCSS.
  • Um thread de trabalho pode facilmente causar um deadlock difícil de depurar.

Além disso, considere usar a fila de trabalho do serializador se você precisar serializar suas operações assíncronas.

Branches de topologia

Se o atributo MF_TOPONODE_WORKQUEUE_MMCSS_CLASS registrar um branch de topologia com o MMCSS, no Windows 8, a Sessão de Mídia usará as filas de trabalho de MT compartilhadas. Em versões anteriores do Windows, a Sessão de Mídia alocou uma nova fila de trabalho.

Dois novos atributos são definidos para registrar um branch de topologia com o MMCSS.

Atributo Descrição
MF_TOPONODE_WORKQUEUE_MMCSS_PRIORITY Especifica a prioridade do thread base.
MF_TOPONODE_WORKQUEUE_ITEM_PRIORITY Especifica a prioridade do item de trabalho.

 

Recomendações

  • Os aplicativos que usam a Sessão de Mídia devem definir MF_TOPONODE_WORKQUEUE_MMCSS_CLASS como "Áudio" para o branch de renderização de áudio e "Reprodução" para o branch de renderização de vídeo.
  • Os aplicativos que usam a Sessão de Mídia devem chamar IMFWorkQueueServices::BeginRegisterTopologyWorkQueuesWithMMCSS na topologia.
  • Para componentes de pipeline, as filas de trabalho são recomendadas em vez de threads de trabalho. Se o componente usar filas de trabalho ou threads de trabalho, implemente IMFRealTimeClientEx.
  • Não crie filas de trabalho privadas, pois isso derrota a finalidade das filas de trabalho da plataforma. Use a fila multithreaded da plataforma ou uma fila serial que encapsula a fila multithreaded da plataforma.
  • Se você precisar serializar operações assíncronas, use uma fila serial.

Resumo

As seguintes APIs de plataforma do Media Foundation relacionadas a threads e filas de trabalho são novas para o Windows 8.

filas de trabalho