Melhorias na fila de trabalho e threading
Este tópico descreve os aprimoramentos no Windows 8 para filas de trabalho e threading na plataforma Microsoft Media Foundation.
- de comportamento do Windows 7
- Melhorias do Windows 8
- Recomendações
- Resumo
- Tópicos relacionados
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 Media Foundation cria várias filas de trabalho padrão. Apenas dois estão documentados como sendo para uso geral da aplicação:
- 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 mensagens.
- MF_WINDOW_WORKQUEUE cria uma fila de trabalho com um loop de mensagens.
Para enfileirar um item de trabalho, chame MFPutWorkItem ou MFPutWorkItemEx. A plataforma executa o item de trabalho invocando a implementação fornecida pelo chamador do IMFAsyncCallback. No Windows 7 e versões anteriores, a plataforma cria um thread por fila de trabalho.
Suporte MMCSS
O Multimedia Class Scheduler Service (MMCSS) gerencia prioridades de thread para que os aplicativos multimídia obtenham fatias regulares de tempo de CPU, sem negar recursos de CPU para aplicativos de prioridade mais baixa. O MMCSS define um conjunto de tarefas que têm diferentes perfis de utilização da CPU. Quando um thread ingressa em uma tarefa do 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 de thread relativa, 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. Esta função usa um ID de fila de trabalho, uma classe MMCSS (nome da tarefa) e o identificador de tarefa MMCSS. Internamente, ele chama AvSetMmThreadCharacteristics com o nome e a ID da tarefa. Depois que uma fila de trabalho é registrada no MMCSS, você pode obter a classe e a ID da tarefa chamando MFGetWorkQueueMMCSSClass e MFGetWorkQueueMMCSSTaskId.
O Media Session fornece acesso de nível um pouco mais alto a essas APIs, por meio da interfaceIMFWorkQueueServices. Esta interface fornece dois métodos principais:
Método | Descrição |
---|---|
BeginRegisterPlatformWorkQueueWithMMCSS | Registra uma fila de trabalho com uma tarefa MMCSS. Esse método é essencialmente um wrapper fino em torno de MFBeginRegisterWorkQueueWithMMCSS, mas você pode passar o valor MFASYNC_CALLBACK_QUEUE_ALL registrar todas as filas de trabalho da plataforma de uma só vez. |
BeginRegisterTopologyWorkQueuesWithMMCSS | Registra uma ramificação da topologia com uma fila de trabalhos. |
Para registrar uma ramificação de topologia, faça o seguinte.
- Defina o atributo MF_TOPONODE_WORKQUEUE_ID no nó de origem da ramificação. Use qualquer valor definido pelo aplicativo.
- Opcionalmente, defina o MF_TOPONODE_WORKQUEUE_MMCSS_CLASS para ingressar na fila de trabalho para uma tarefa MMCSS.
- 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 ramificação de topologia, operações de pipeline assíncronas são executadas na fila de trabalho atribuída à ramificação.
IMFRealTimeClient
A interfaceIMFRealTimeClientdestina-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:
- Se o componente de pipeline criar um thread de trabalho, o método deIMFRealTimeClient::RegisterThreadsnotificará o componente a qual classe MMCSS ingressar.
- Se o componente de pipeline usa uma fila de trabalhos, o métodoIMFRealTimeClient::SetWorkQueueinforma ao componente qual fila de trabalho usar.
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 oferece suporte a um novo tipo de fila de trabalho chamada fila multithreaded. Uma fila multithreaded usa um pool de threads do sistema para despachar itens de trabalho. A fila multithreaded é melhor dimensionada 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 opções 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 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 fica disponível, o próximo item de trabalho na fila é despachado. 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 é enviado até que o item anterior seja concluído.
O código a seguir cria uma fila de serializador sobre a fila multithreaded da plataforma.
DWORD workQueueID;
hr = MFAllocateSerialWorkQueue(MFASYNC_CALLBACK_QUEUE_MULTITHREADED, &workQueueID);
Mais de uma fila serial pode encapsular a mesma fila multithreaded. As filas seriais compartilham o mesmo pool de threads e a execução serializada é imposta dentro de 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. Esta alteração preserva a compatibilidade com versões anteriores.
Filas de trabalho de tarefas compartilhadas
Para trabalhar corretamente com o agendador do kernel, deve haver uma fila de trabalho multithreaded para cada tarefa MMCSS que você usa. A plataforma Media Foundation aloca estes conforme necessário, até um 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 ainda não existir uma fila de trabalhos para esta tarefa, a função aloca uma nova fila de trabalho MT e imediatamente a associa à tarefa MMCSS. Se já existir uma fila de trabalhos 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 eventos para serem sinalizados. Se um componente precisar aguardar a sinalização de um evento, 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 ponteiro deIMFAsyncResult. Quando o evento é sinalizado, a fila de espera invoca seu retorno de chamada. Há uma fila de espera de plataforma única; Os aplicativos não podem criar suas próprias filas de espera.
Melhorias no suporte ao MMCSS
As novas funções da plataforma Media Foundation a seguir estão relacionadas ao MMCSS.
Função | Descrição |
---|---|
MFBeginRegisterWorkQueueWithMMCSSEx | Registra uma fila de trabalho com o MMCSS. Esta função inclui um parâmetro para especificar a prioridade relativa do thread. Internamente, esse valor é traduzido em uma chamada para AvSetMmThreadPriority. |
MFGetWorkQueueMMCSSPriority | Consulta a prioridade de uma fila de trabalhos. |
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 a ramificação de renderização de áudio. Defina o atributo como "Reprodução" para a ramificação de renderização de vídeo.
IMFRealTimeClientEx
O IMFRealTimeClientEx interface 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 IMFRealTimeClient::UnregisterThreads método. |
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 melhor dimensionadas porque usam os pools de threads do sistema operacional.
- A plataforma lida com os detalhes de 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 precisar serializar suas operações assíncronas.
Ramificações de topologia
Se o atributo MF_TOPONODE_WORKQUEUE_MMCSS_CLASS registrar uma ramificação 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 uma ramificação 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 a ramificação de renderização de áudio e "Reprodução" para a ramificação 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, 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 anula o objetivo 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 da plataforma Media Foundation relacionadas a threads e filas de trabalho são novas para o Windows 8.
- MF_TOPONODE_WORKQUEUE_ITEM_PRIORITY
- MF_TOPONODE_WORKQUEUE_MMCSS_PRIORITY
- MFAllocateSerialWorkQueue
- MFBeginRegisterWorkQueueWithMMCSSEx
- MFGetWorkQueueMMCSSPriority
- MFPutWaitingWorkItem
- MFPutWorkItem2
- MFPutWorkItemEx2
- MFRegisterPlatformWithMMCSS
- MFUnregisterPlatformFromMMCSS
- MFLockSharedWorkQueue
- IMFRealTimeClientEx
Tópicos relacionados