Сравнение структур данных синхронизации с интерфейсом Windows API
В этом разделе сравнивается поведение структур данных синхронизации, предоставленных средой выполнения с параллелизмом и интерфейсом Windows API.
Структуры данных синхронизации, предоставленные средой выполнения с параллелизмом, созданы по модели совместных потоков. В модели совместных потоков примитивы синхронизации явно передают ресурсы для обработки другим потокам. Этим она отличается от модели потоков с вытеснением, в которой ресурсы для обработки передаются другим потокам управляющим планировщиком или операционной системой.
critical_section
Класс Concurrency::critical_section напоминает структуру CRITICAL_SECTION Windows, потому что он может использоваться только потоками одного процесса. Дополнительные сведения о критических секциях в интерфейсе Windows API см. в разделе Объекты критических секций.
reader_writer_lock
Класс Concurrency::reader_writer_lock напоминает тонкие блокировки чтения и записи (SRW) Windows. В следующей таблице перечислены сходства и различия этих сущностей.
Функция |
reader_writer_lock |
Блокировка SRW |
---|---|---|
Повторные входы недопустимы |
Да |
Да |
Возможность повысить уровень средства чтения до уровня средства записи (поддержка обновлений) |
Нет |
Нет |
Возможность понизить уровень средства записи до уровня средства чтения (поддержка понижения уровня) |
Нет |
Нет |
Блокировка предпочтения записи |
Да |
Нет |
Доступ к средствам записи по методу FIFO |
Да |
Нет |
Дополнительные сведения о блокировках SRW см. в разделе Тонкие блокировки чтения/записи (SRW) в пакете SDK данной платформы.
event
Класс Concurrency::event напоминает неименованное событие ручного сброса Windows. Однако объект event предназначен для использования в совместных сценариях, а событие Windows — в сценариях вытеснения. Дополнительные сведения о событиях Windows см. в разделе Объекты Event.
Пример
Описание
Чтобы лучше понять разницу между классом event и событиями Windows, рассмотрим следующий пример. В этом примере планировщик создает не более двух одновременных задач, а затем вызывает две аналогичные функции, использующие класс event и событие ручного сброса Windows. Каждая функция сначала создает несколько задач, которые ожидают перехода общего события в сигнальное состояние. Затем каждая функция передается выполняемым задачам и сигнализирует событие. После этого каждая функция ожидает событие, о котором был послан сигнал.
Код
// 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();
}
Комментарии
В данном примере получается следующий результат.
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.
Поскольку класс event предназначен для использования в совместных сценариях, планировщик может перераспределить ресурсы для обработки другому контексту, если событие ожидает перехода в сигнальное состояние. Таким образом, версии, использующей класс event, удается выполнить больше работы. В версии, использующей события Windows, каждая ожидающая задача должна перейти в сигнальное состояние, прежде чем будет запущена следующая задача.
Дополнительные сведения о задачах см. в разделе Параллелизм задач (среда выполнения с параллелизмом).
См. также
Ссылки
Тонкие блокировки чтения и записи (SRW)