Барьер - это концепция, также известная какрандеву, это точка синхронизации между несколькими контекстами выполнения (волокнами). Барьер сконфигурирован для определенного количества волокон (n
), и по мере того, как волокна достигают барьера, они должны ждать, пока всеn
волокна не достигнут. Как толькоn
— волокно достигло барьера, все ожидающие волокна могут продолжиться, и барьер сбрасывается.
Существенным является тот факт, что барьер автоматически сбрасывается. Рассмотрим случай, в котором вы запускаете некоторое количество волокон и хотите подождать, пока первый из них не будет завершен. У вас может возникнуть соблазн использоватьбарьер2
в качестве механизма синхронизации, заставляя каждое новое волокно вызывать свойбарьер:: ждите
метод, а затем вызыватьждать
в пусковом волокне, чтобы ждать, пока первое другое волокно не завершится.
Это фактически разблокирует пусковое волокно. Недостатком является то, что он будет продолжать блокироватьоставшиесяволокна.
Рассмотрим следующий сценарий:
- Волокони #8220;основнойи #8221;запускает волокна A, B, C и D, затем вызывает
барьер::ждите()
.
- Волокно C заканчивается первым и также вызывает
барьер::ждать[]
.
- Волокнои #8220;основноеи #8221;разблокировано, по желанию.
- Волокно B вызывает
барьер::ждите
. Волокно Bзаблокировано!
- Волокно А вызывает
барьер::ждите()
. Волокна A и B разблокированы.
- Волокно D вызывает
барьер::ждать
. Волокно D блокируется на неопределенный срок.
(См. также, когда_любое, простое завершение.)
![[Note]](/img/note.png) |
Note |
Неразумно связывать продолжительность жизни барьера с любым из его участвующих волокон. Хотя концептуально все ожидающие волокна пробуждаютсяи #8220;одновременно,и #8221;из-за природы волокон, на практике они пробуждаются один за другим в неопределенном порядке.Остальные ожидающие волокна все равно будут заблокированы вожидании() , которые должны, прежде чем вернуться, получить доступ к элементам данных в барьерном объекте. |
#include <boost/fiber/barrier.hpp>
namespace boost {
namespace fibers {
class barrier {
public:
explicit barrier( std::size_t);
barrier( barrier const&) = delete;
barrier & operator=( barrier const&) = delete;
bool wait();
};
}}
Случаибарьера
не являются копируемыми или подвижными.
explicit barrier( std::size_t initial);
- Effects:
Постройте барьер дляисходных
волокон.
- Throws:
волокно_ошибка
- Error Conditions:
недействительный_аргумент: еслиначальный
равен нулю.
bool wait();
- Effects:
Блок доначальных
волокон вызваложидание
на*это
. Когданачальное
-th волокно вызываетожидание
, все ожидающие волокна разблокированы, и барьер сбрасывается.
- Returns:
истинно
для ровно одного волокна из каждой партии ожидающих волокон,ложно
в противном случае.
- Throws:
волокно_ошибка