Поделиться через


Структуры данных синхронизации

Среда выполнения параллельных вычислений предоставляет несколько структур данных, которые позволяют синхронизировать доступ к общим данным из нескольких потоков. Эти структуры данных полезны при использовании общих данных, которые редко изменяются. Объект синхронизации, например, критически важный раздел, приводит к тому, что другие потоки будут ожидать, пока общий ресурс не будет доступен. Таким образом, если вы используете такой объект для синхронизации доступа к данным, которые часто используются, вы можете потерять масштабируемость в приложении. Библиотека параллельных шаблонов (PPL) предоставляет класс параллелизма::комбинируемый класс, который позволяет совместно использовать ресурс между несколькими потоками или задачами без необходимости синхронизации. Дополнительные сведения о классе см. в разделе "Параллельные combinable контейнеры и объекты".

Разделы

В этом разделе подробно описаны следующие типы блоков асинхронных сообщений:

критическая секция

Класс concurrency::critical_section представляет кооперативный объект взаимного исключения, который уступает другим задачам вместо их вытеснения. Критические разделы полезны, если для нескольких потоков требуется эксклюзивный доступ на чтение и запись к общим данным.

Класс critical_section не является повторно входящим. Метод concurrency::critical_section::lock вызывает исключение типа concurrency::improper_lock, если он вызывается потоком, который уже владеет блокировкой.

Методы и компоненты

В следующей таблице показаны важные методы, определенные классом critical_section .

Метод Описание
замок Получает критически важный раздел. Контекст вызова блокируется до тех пор, пока он не получит блокировку.
try_lock Пытается получить критически важный раздел, но не блокируется.
разблокировать Освобождает критически важный раздел.

[В начало]

блокировка читателя и писателя

Класс конкурентный::reader_writer_lock предоставляет потокобезопасные операции чтения и записи для общих данных. Используйте блокировки чтения/записи, когда нескольким потокам требуется одновременный доступ для чтения к общему ресурсу, но запись в этот ресурс происходит редко. Этот класс предоставляет доступ на запись к объекту только одному потоку в один момент времени.

Класс reader_writer_lock может работать лучше, чем critical_section класс, так как critical_section объект получает монопольный доступ к общему ресурсу, что предотвращает одновременный доступ на чтение.

Как и класс critical_section, класс reader_writer_lock представляет собой объект кооперативного взаимного исключения, который предоставляет управление другим задачам вместо их упреждения.

Когда поток, который должен записывать в общий ресурс, получает блокировку для чтения/записи, другие потоки, которые должны также иметь доступ к ресурсу, блокируются до тех пор, пока поток записи не освободит блокировку. Класс reader_writer_lock является примером блокировки с предпочтением записи, которая сначала разблокирует ожидающих писателей, а затем ожидающих читателей.

Класс critical_section, как и класс reader_writer_lock, не обладает свойством повторного входа. Методы concurrency::reader_writer_lock::lock и concurrency::reader_writer_lock::lock_read вызывают исключение типа improper_lock, если их вызывает поток, который уже удерживает блокировку.

Примечание.

reader_writer_lock Поскольку класс не является неповторяемым, вы не можете обновлять блокировку только для чтения до блокировки для чтения и записи или понижать уровень блокировки для чтения и записи до блокировки только для чтения. Выполнение любой из этих операций приводит к неуказаенному поведению.

Методы и компоненты

В следующей таблице показаны важные методы, определенные классом reader_writer_lock .

Метод Описание
замок Получает доступ на чтение и запись к блокировке.
try_lock Пытается получить доступ на чтение и запись к замку, но не блокирует процесс.
замок_чтение Получает доступ только для чтения к механизму блокировки.
try_lock_read Пытается получить доступ только для чтения к механизму блокировки, при этом не блокируясь.
разблокировать Освобождает блокировку.

[В начало]

scoped_lock и scoped_lock_read

Классы critical_section и reader_writer_lock предоставляют вложенные вспомогательные классы, упрощающие работу с объектами взаимного исключения. Эти вспомогательные классы называются блокировками с областью действия.

Класс critical_section содержит класс concurrency::critical_section::scoped_lock. Конструктор получает доступ к предоставленному critical_section объекту. Деструктор освобождает доступ к объекту. Класс reader_writer_lock содержит класс concurrency::reader_writer_lock::scoped_lock, который похож на critical_section::scoped_lock, но управляет доступом на запись к данному объекту reader_writer_lock. Класс reader_writer_lock также содержит класс параллелизма::reader_writer_lock::scoped_lock_read . Этот класс управляет доступом на чтение к предоставленному reader_writer_lock объекту.

Заблокированные области обеспечивают несколько преимуществ при работе с объектами critical_section и reader_writer_lock вручную. Как правило, вы выделяете блокировку с ограниченной областью видимости на стеке. Блокировка с ограниченной областью освобождает доступ к объекту взаимного исключения автоматически при его уничтожении; Таким образом, вы не разблокируете базовый объект вручную. Это полезно, если функция содержит несколько return инструкций. Локи с областью видимости также могут помочь в написании кода, безопасного с точки зрения обработки исключений. throw Когда инструкция вызывает распаковку стека, вызывается деструктор любой активной блокировки в области видимости, поэтому объект взаимного исключения всегда освобождается правильно.

Примечание.

Если вы используете critical_section::scoped_lockклассы , reader_writer_lock::scoped_lockи reader_writer_lock::scoped_lock_read классы, не освобождайте вручную доступ к базовому объекту взаимного исключения. Это может поместить среду выполнения в недопустимое состояние.

событие

Класс concurrency::event представляет объект синхронизации, который может находиться в состоянии сигнализации или в состоянии отсутствия сигнализации. В отличие от объектов синхронизации, таких как критически важные разделы, цель которых — защитить доступ к общим данным, события синхронизируют поток выполнения.

Класс event полезен, когда одна задача завершила работу для другой задачи. Например, одна задача может сигнализировать другой задаче о том, что она считывает данные из сетевого подключения или из файла.

Методы и компоненты

В следующей таблице показаны несколько важных методов, определенных классом event .

Метод Описание
ждать Ожидает, пока событие станет сигналом.
установить Устанавливает событие в сигнальное состояние.
reset; Устанавливает событие в несигнальное состояние.
wait_for_multiple Ожидает передачи сигнала о нескольких событиях.

Пример

Пример использования event класса см. в разделе "Сравнение структур данных синхронизации" с API Windows.

[В начало]

Сравнение структур данных синхронизации с интерфейсом Windows API
Сравнивает поведение структур данных синхронизации с данными, предоставляемыми API Windows.

Среда выполнения с параллелизмом
Описывает среду выполнения с параллелизмом, которая упрощает процесс параллельного программирования и содержит ссылки на соответствующие разделы.