Создать стандартное обещание для каждого потока. Вызовите get_future () для каждого обещания, чтобы получить связанный объект std :: future. Храните эти фьючерсы в глобальном векторе, доступном для всех потоков, например, asyncfutures. Затем в каждом потоке вызовите set_value для std :: promise для этого потока после создания соединения, и вместо while l oop выполните:
for (auto fut : asyncfutures) {
fut.wait();
}
, затем продолжите действия потока.
Функция wait () выполняет ожидание, пока другой поток вызовет set_value в своем обещании. После того, как все другие потоки будут вызывать set_value (что происходит после того, как они установят sh соединение), завершается, затем завершается for l oop, и все потоки вместе go on используют соединение.
Если вы хотите, чтобы все потоки ожидали не только друг друга, но и какого-либо события в главном потоке, вы можете добавить другое будущее к async_futures и вызвать set_value для объекта обещания, как только событие будет достигнуто.
На этом этапе поток не возвращается, поэтому объект подключения не уничтожается.
Обратите внимание, что std :: promise является шаблоном. Вы можете посмотреть больше об обещаниях и фьючерсах на cppreference.com.
РЕДАКТИРОВАТЬ: C ++ 20 добавил тип latch
в стандартную библиотеку ISO C ++. Это позволяет вам создать защелку с его счетчиком, инициализированным в количестве потоков, которые должны быть запущены, и иметь каждый поток, вызывающий arrive_and_wait
, когда поток достигает точки синхронизации. Это будет блокировать поток до тех пор, пока другие потоки также не достигнут точки синхронизации.
По состоянию на 23 апреля 2020 года поддержка C ++ 20, как правило, отсутствует или является частичной среди компиляторов, но она должна наверстать упущенное в пределах следующий год или два.