Comparando as estruturas de dados de sincronização para a API do Windows.
Este tópico compara o comportamento das estruturas de dados de sincronização que são fornecidos pelo Runtime de simultaneidade aos fornecidos pela API do Windows.
As estruturas de dados de sincronização são fornecidas pelo Runtime de simultaneidade siga a modelo de threading cooperativo. No modelo de threading cooperativo, primitivos de sincronização yield explicitamente os seus recursos de processamento para outros segmentos. Isso difere do modelo de threading preemptivo, onde os recursos de processamento são transferidos para outros threads pelo Agendador de controlar ou sistema operacional.
CRITICAL_SECTION
O Concurrency::critical_section classe se parece com o Windows CRITICAL_SECTION estrutura porque ele pode ser usado somente por segmentos de um processo. Para obter mais informações sobre as seções críticas na API do Windows, consulte Objetos de seção crítica.
reader_writer_lock
O Concurrency::reader_writer_lock classe se assemelha a bloqueios de leitor/gravador reduzido (SRW) do Windows. A tabela a seguir explica as semelhanças e diferenças.
Característica |
reader_writer_lock |
Bloqueio de SRW |
---|---|---|
Não reentrante |
Sim |
Sim |
Poderá promover um leitor de um gravador (suporte de atualização) |
Não |
Não |
Rebaixar um gravador de um leitor (downgrade suporte) |
Não |
Não |
Bloqueio de gravação preferência |
Sim |
Não |
Acesso de FIFO para gravadores |
Sim |
Não |
Para obter mais informações sobre bloqueios de SRW, consulte bloqueios de leitor/gravador reduzido (SRW) na plataforma SDK.
Evento
O Concurrency::event classe se assemelha a um evento de redefinição manual sem nome, do Windows. No entanto, um event objeto se comporta de forma cooperativa, enquanto um evento do Windows se comporta preventivamente. Para obter mais informações sobre eventos do Windows, consulte Os objetos de evento.
Exemplo
Descrição
Para entender melhor a diferença entre o event classe e eventos do Windows, considere o exemplo a seguir. Este exemplo permite que o Agendador criar no máximo duas tarefas simultâneas e chama semelhante duas funções que usam o event classe e um evento de redefinição manual do Windows. Cada função primeiro cria várias tarefas que aguardar um evento compartilhado ficar sinalizado. Cada função, em seguida, gera para as tarefas em execução e, em seguida, sinalize o evento. Cada função aguarda 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 saída de exemplo a seguir:
Cooperative event:
Context 0: waiting on an event.
Context 1: waiting on an event.
Context 2: waiting on an event.
Context 3: waiting on an event.
Context 4: waiting on an event.
Setting the event.
Context 5: received the event.
Context 6: received the event.
Context 7: received the event.
Context 8: received the event.
Context 9: received the event.
Windows event:
Context 10: waiting on an event.
Context 11: waiting on an event.
Setting the event.
Context 12: received the event.
Context 14: waiting on an event.
Context 15: received the event.
Context 16: waiting on an event.
Context 17: received the event.
Context 18: waiting on an event.
Context 19: received the event.
Context 13: received the event.
Porque o event classe se comporta de forma cooperativa, o Agendador pode realocar os recursos de processamento para outro contexto quando um evento que está esperando para entrar em estado sinalizado. Portanto, mais trabalho é realizado pela versão que usa o event classe. Na versão que usa os eventos do Windows, a cada tarefa de espera deve inserir o estado sinalizado antes que a próxima tarefa seja iniciada.
Para obter mais informações sobre tarefas, consulte Paralelismo de tarefas (Runtime de simultaneidade).
Consulte também
Referência
Slim bloqueios de leitor/gravador (SRW)