std::mutex mutex;
std::condition_variable cv;
uint8_t size = 2;
uint8_t count = size;
uint8_t direction = -1;
const auto sync = [&size, &count, &mutex, &cv, &direction]() //.
{
{
std::unique_lock<std::mutex> lock(mutex);
auto current_direction = direction;
if (--count == 0)
{
count = size;
direction *= -1;
cv.notify_all();
}
else
{
cv.wait(lock,
[&direction, ¤t_direction]() //.
{ return direction != current_direction; });
}
}
};
как указано в первом непринятом ответе многоразового барьера
«поколение» должно храниться внутри объекта-барьера, чтобы следующее поколение не могло манипулировать «условием» пробуждения текущего поколения для данного набора потоков. Что мне не нравится в первом непринятом ответе, так это растущий счетчик поколений, я считаю, что нам нужно только различать максимум два поколения, то есть если поток удовлетворил условию ожидания и начал другой вызов барьерной синхронизации в качестве второго непринятого решения предполагает, что второе решение, однако, было несколько сложным, и я считаю, что приведенного выше фрагмента было бы даже достаточно (в настоящее время реализовано локально внутри основного, но может быть абстрагировано в структуру). Прав ли я в своем «убеждении», что барьер можно использовать одновременно не более чем для двух поколений?
count
равно 0 в точке захвата. - person Bathsheba   schedule 26.09.2017sync
достаточное количество раз, чтобы снова изменить направление. Затем поток 1 обнаружил бы, что условие ложно, предположил бы ложное пробуждение и снова заснул бы. В конечном итоге он проснется, когда направление снова изменится, в третий (или, возможно, пятый, илиN
th для сколь угодно большого нечетногоN
) времени. - person Igor Tandetnik   schedule 30.09.2017