Partilhar via


Contextos

Este documento descreve a função dos contextos no Concurrency Runtime. Uma thread ligada a um agendador é conhecida como contexto de execução ou apenas contexto. A função concurrency::wait e a classe concurrency::Context permitem controlar o comportamento dos contextos. Use a wait função para suspender o contexto atual por um tempo especificado. Use a Context Class quando precisares de mais controlo sobre quando os contextos bloqueiam, desbloqueiam e cedem, ou quando quiseres sobrescrever o contexto atual.

Sugestão

O Concurrency Runtime fornece um agendador padrão e, portanto, você não é obrigado a criar um em seu aplicativo. Como o Agendador de Tarefas ajuda a ajustar o desempenho de seus aplicativos, recomendamos que você comece com a Biblioteca de Padrões Paralelos (PPL) ou a Biblioteca de Agentes Assíncronos se você for novo no Tempo de Execução de Simultaneidade.

A função de espera

A função concurrency::wait produz cooperativamente a execução do contexto atual por um número especificado de milissegundos. O tempo de execução usa o tempo de rendimento para executar outras tarefas. Após o decorrer do tempo especificado, o sistema de execução reagenda o contexto para execução. Portanto, a wait função pode suspender o contexto atual por mais tempo do que o valor fornecido para o milliseconds parâmetro.

Passar 0 (zero) para o milliseconds parâmetro faz com que o tempo de execução suspenda o contexto atual até que todos os outros contextos ativos tenham a oportunidade de executar o trabalho. Isso permite que você ceda uma tarefa a todas as outras tarefas ativas.

Exemplo

Para obter um exemplo que usa a wait função para produzir o contexto atual e, assim, permitir que outros contextos sejam executados, consulte Como usar grupos de agendamento para influenciar a ordem de execução.

A classe de contexto

A classe concurrency::Context fornece uma abstração de programação para um contexto de execução e oferece dois recursos importantes: a capacidade de bloquear, desbloquear e produzir o contexto atual de forma cooperativa e a capacidade de sobrescrever o contexto atual.

Bloqueio cooperativo

A classe Context permite bloquear ou suspender o contexto de execução atual. Bloquear ou ceder é útil quando o contexto atual não pode continuar porque um recurso não está disponível.

O método concurrency::Context::Block bloqueia o contexto atual. Um contexto bloqueado cede seus recursos de processamento para que a execução do sistema possa realizar outras tarefas. O método concurrency::Context::Unblock desbloqueia um contexto bloqueado. O Context::Unblock método deve ser chamado de um contexto diferente daquele que chamou Context::Block. O tempo de execução lança simultaneidade::context_self_unblock se um contexto tentar se desbloquear.

Para bloquear e desbloquear cooperativamente um contexto, você normalmente chama concurrency::Context::CurrentContext para recuperar um ponteiro para o Context objeto associado ao thread atual e salvar o resultado. Em seguida, você chama o Context::Block método para bloquear o contexto atual. Mais tarde, chame Context::Unblock de um contexto separado para desbloquear o contexto bloqueado.

Você deve corresponder a cada par de chamadas para Context::Block e Context::Unblock. O tempo de execução lança simultaneidade::context_unblock_unbalanced quando o método Context::Block ou Context::Unblock é chamado consecutivamente sem uma chamada correspondente para o outro método. No entanto, você não precisa ligar Context::Block antes de ligar Context::Unblock. Por exemplo, se um contexto chama Context::Unblock antes de outro contexto chama Context::Block para o mesmo contexto, esse contexto permanece desbloqueado.

O método concurrency::Context::Yield cede a execução para permitir que o runtime execute outras tarefas e, em seguida, recalendarize o contexto para execução. Quando se chama o Context::Block método, o ambiente de execução não reagenda o contexto.

Exemplo

Para obter um exemplo que usa os métodos Context::Block, Context::Unblock e Context::Yield para implementar uma classe de semáforo cooperativo, consulte Como: Usar a classe de contexto para implementar um semáforo cooperativo.

Excesso de subscrição

O agendador padrão cria tantas threads quantas as threads de hardware disponíveis. Você pode usar sobresubscrição para criar threads adicionais para um determinado thread de hardware.

Para operações computacionais intensivas, a sobrescrição normalmente não é escalável porque introduz sobrecarga adicional. No entanto, para tarefas que têm alta latência, por exemplo, a leitura de dados de disco ou de uma conexão de rede, a sobresubscrição pode melhorar a eficiência geral de algumas aplicações.

Observação

Habilite a assinatura excessiva somente a partir de um thread criado pelo Concurrency Runtime. A sobrescrição não tem efeito quando é chamada a partir de uma thread que não foi criada pelo ambiente de execução (incluindo a thread principal).

Para habilitar a sobreassinatura no contexto atual, chame o método concurrency::Context::Oversubscribe com o _BeginOversubscription parâmetro definido como true. Quando você habilita a superassinatura em um thread que foi criado pelo Concurrency Runtime, isso faz com que o tempo de execução crie um thread adicional. Depois que todas as tarefas que exigem sobrecarga de recursos forem concluídas, chame Context::Oversubscribe com o parâmetro _BeginOversubscription definido como false.

Você pode habilitar a superassinatura várias vezes a partir do contexto atual, mas deve desativá-la o mesmo número de vezes que a habilita. A sobresubscrição também pode ser aninhada; ou seja, uma tarefa que é criada por outra tarefa que usa oversubscription também pode sobrescrever seu contexto. No entanto, se uma tarefa aninhada e seu pai pertencerem ao mesmo contexto, somente a chamada mais externa para Context::Oversubscribe causará a criação de um thread adicional.

Observação

O executável lança simultaneidade::invalid_oversubscribe_operation se a sobreassinatura for desativada antes de ser ativada.

Exemplo

Para obter um exemplo que usa a assinatura excessiva para compensar a latência causada pela leitura de dados de uma conexão de rede, consulte Como usar a assinatura excessiva para compensar a latência.

Ver também

Agendador de Tarefas
Como: Usar grupos de agendamento para influenciar a ordem de execução
Como: Usar a classe de contexto para implementar um semáforo cooperativo
Como usar a sobresubscrição para compensar a latência