Барьер - это концепция, также известная какрандеву, это точка синхронизации между несколькими контекстами выполнения (волокнами). Барьер сконфигурирован для определенного количества волокон (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:
волокно_ошибка