Comparando estruturas de dados de sincronização à API
Este tópico compara o comportamento de estruturas de dados de sincronização que são fornecidas em tempo de execução de simultaneidade àquelas fornecidas pelo Windows API.
Estruturas de dados de sincronização que são fornecidas em tempo de execução de simultaneidade seguem o modelo de threads cooperativo.No modelo de threads cooperativo, primitivos de sincronização produzem explicitamente os recursos de processamento para outros segmentos.Isso difere do modelo de threads preventivo, onde o processamento de recursos é transferido para outros segmentos por agendador ou pelo sistema operacional de controle.
critical_section
A classe de concurrency::critical_section é semelhante a estrutura do Windows CRITICAL_SECTION porque pode ser usada somente os segmentos de um processo.Para obter mais informações sobre as seções críticos no Windows API, consulte Objetos de seção crítica.
reader_writer_lock
A classe de concurrency::reader_writer_lock é semelhante a magros bloqueios de (SRW) de leitura/gravação melhorado do Windows.A tabela a seguir descreve as semelhanças e diferenças.
Recurso |
reader_writer_lock |
Bloqueio de SRW |
---|---|---|
Não reentrante |
Sim |
Sim |
Pode elevar um leitor a um gravador (suporte de atualização) |
Não |
Não |
Pode prejudicar um gravador a um leitor (o suporte de downgrade) |
Não |
Não |
Bloqueio de preferência contra gravação |
Sim |
Não |
Acesso de PEPS a criadores |
Sim |
Não |
Para obter mais informações sobre os bloqueios de SRW, consulte Bloqueios de (SRW) magro de leitura/gravação melhorado na plataforma SDK.
evento
A classe de concurrency::event é semelhante a um evento sem nome, manual- redefinido Windows.No entanto, um objeto de event se comporta cooperativa, enquanto um evento do Windows se comporta preemptively.Para obter mais informações sobre eventos do Windows, consulte Objetos de evento.
Exemplo
Descrição
Para compreender melhor a diferença entre a classe de event e os eventos do Windows, considere o seguinte exemplo.Este exemplo permite que o agendador para criar no máximo duas tarefas simultâneas e então chamar em duas funções semelhantes que usam a classe de event e um evento manual- redefinido Windows.Cada função primeiramente cria várias tarefas que assumem um evento compartilhado para tornar-se sinalizadas.Cada função resulta nas tarefas em execução e sinaliza no evento.Cada função aguarde o evento signaled.
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 produz a seguinte saída de exemplo:
Porque a classe de event se comporta cooperativa, o agendador pode realocar recursos de processamento para outro contexto quando um evento está aguardando para entrar no estado signaled.Como consequência, mais trabalho é feito pela versão que usa a classe de event .Na versão que usa eventos do Windows, cada tarefa de espera deve ir para o estado signaled antes que a tarefa seguinte seja iniciada.
Para obter mais informações sobre as tarefas, consulte Paralelismo de tarefa (tempo de execução de simultaneidade).
Consulte também
Referência
Bloqueios de (SRW) magro de leitura/gravação melhorado