Comparando estruturas de dados com a API do Windows
Este tópico compara o comportamento das estruturas de dados de sincronização que são fornecidas em tempo de execução de simultaneidade aquelas fornecidas pela API do windows.
As estruturas de dados de sincronização que são fornecidas em tempo de execução de simultaneidade seguem o modelo de threading cooperativo. No modelo de threading cooperativo, e os primitivos de sincronização são explicitamente seus recursos de processamento para outros threads. Isso difere do modelo de threading preemptivo, onde o processamento de recursos é transferida para outros threads por agendador ou pelo sistema operacional de controle.
critical_section
A classe de concurrency::critical_section é semelhante à estrutura de CRITICAL_SECTION do windows porque pode ser usada apenas por threads de um processo. Para obter mais informações sobre as seções críticos na API do windows, consulte Objetos da seção crítica.
reader_writer_lock
A classe de concurrency::reader_writer_lock se assemelha a bloqueios magros (SRW) de leitor/gravador do windows. A tabela a seguir explica as semelhanças e diferenças.
Recurso |
reader_writer_lock |
Bloqueio de SRW |
---|---|---|
Não reentrante |
Sim |
Sim |
Poderá elevar um leitor em um gravador (o suporte à atualização) |
Não |
Não |
Pode degradar um gravador a um leitor (suporte de downgrade) |
Não |
Não |
Bloqueio de gravação preferência |
Sim |
Não |
Acesso do FIFO aos gravadores |
Sim |
Não |
Para obter mais informações sobre bloqueios de SRW, consulte Bloqueios de slim (SRW) de leitura/gravação no SDK da plataforma.
evento
A classe de concurrency::event é semelhante a um sem-nome, evento manual redefinido o windows. No entanto, um objeto de event se comporta cooperativa, enquanto que um evento do windows se comporta preemptivo. Para obter mais informações sobre eventos do windows, consulte Objetos de evento.
Exemplo
Descrição
Para entender melhor a diferença entre a classe de event e eventos do windows, considere o exemplo a seguir. Esse exemplo ativa o agendador para criar no máximo duas tarefas simultâneas e então chama duas funções semelhantes que usam a classe de event e um evento manual redefinido o windows. Cada função criar várias tarefas que esperam por um evento compartilhado para se tornarem sinalizadas. Cada função gerencie às tarefas em execução e sinaliza o evento. Cada função espera que o evento sinalizado.
Código
// event-comparison.cpp
// compile with: /EHsc
#include <windows.h>
#include <concrtrm.h>
#include <ppl.h>
#include <iostream>
#include <sstream>
using namespace concurrency;
using namespace std;
// Demonstrates the usage of cooperative events.
void RunCooperativeEvents()
{
// An event object.
event e;
// Create a task group and execute five tasks that wait for
// the event to be set.
task_group tasks;
for (int i = 0; i < 5; ++i)
{
tasks.run([&] {
// Print a message before waiting on the event.
wstringstream ss;
ss << L"\t\tContext " << GetExecutionContextId()
<< L": waiting on an event." << endl;
wcout << ss.str();
// Wait for the event to be set.
e.wait();
// Print a message after the event is set.
ss = wstringstream();
ss << L"\t\tContext " << GetExecutionContextId()
<< L": received the event." << endl;
wcout << ss.str();
});
}
// Wait a sufficient amount of time for all tasks to enter
// the waiting state.
Sleep(1000L);
// Set the event.
wstringstream ss;
ss << L"\tSetting the event." << endl;
wcout << ss.str();
e.set();
// Wait for all tasks to complete.
tasks.wait();
}
// Demonstrates the usage of preemptive events.
void RunWindowsEvents()
{
// A Windows event object.
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, TEXT("Windows Event"));
// Create a task group and execute five tasks that wait for
// the event to be set.
task_group tasks;
for (int i = 0; i < 5; ++i)
{
tasks.run([&] {
// Print a message before waiting on the event.
wstringstream ss;
ss << L"\t\tContext " << GetExecutionContextId()
<< L": waiting on an event." << endl;
wcout << ss.str();
// Wait for the event to be set.
WaitForSingleObject(hEvent, INFINITE);
// Print a message after the event is set.
ss = wstringstream();
ss << L"\t\tContext " << GetExecutionContextId()
<< L": received the event." << endl;
wcout << ss.str();
});
}
// Wait a sufficient amount of time for all tasks to enter
// the waiting state.
Sleep(1000L);
// Set the event.
wstringstream ss;
ss << L"\tSetting the event." << endl;
wcout << ss.str();
SetEvent(hEvent);
// Wait for all tasks to complete.
tasks.wait();
// Close the event handle.
CloseHandle(hEvent);
}
int wmain()
{
// Create a scheduler policy that allows up to two
// simultaneous tasks.
SchedulerPolicy policy(1, MaxConcurrency, 2);
// Attach the policy to the current scheduler.
CurrentScheduler::Create(policy);
wcout << L"Cooperative event:" << endl;
RunCooperativeEvents();
wcout << L"Windows event:" << endl;
RunWindowsEvents();
}
Comentários
Este exemplo gerencia a seguinte saída de exemplo:
Como a classe de event se comporta cooperativa, o agendador pode realocar os recursos de processamento para outro contexto quando um evento está aguardando para entrar no estado sinalizado. Consequentemente, mais trabalho é realizado pela versão que usa a classe de event . Na versão que usa eventos do windows, cada tarefa de espera deve entrar no estado sinalizado antes da próxima tarefa é iniciada.
Para obter mais informações sobre tarefas, consulte Paralelismo de tarefa (tempo de execução de simultaneidade).
Consulte também
Referência
Bloqueios de slim (SRW) de leitura/gravação