The class template std::barrier provides a thread-coordination mechanism that blocks a group of threads of known size until all threads in that group have reached the barrier. Unlike std::latch, barriers are reusable: once a group of arriving threads are unblocked, the barrier can be reused. Unlike std::latch, barriers execute a possibly empty callable before unblocking threads.
#include<iostream>#include<barrier>#include<thread>#include<vector>#include<syncstream>voidtask(std::barrier<>&sync_point,intid){std::osyncstream(std::cout)<<"Task "<<id<<" is starting.\n";// 模拟工作std::this_thread::sleep_for(std::chrono::milliseconds(100*id));std::osyncstream(std::cout)<<"Task "<<id<<" is waiting at the barrier.\n";sync_point.arrive_and_wait();std::osyncstream(std::cout)<<"Task "<<id<<" has passed the barrier.\n";}intmain(){constintnum_threads=5;std::barriersync_point(num_threads);std::vector<std::thread>threads;for(inti=0;i<num_threads;++i){threads.emplace_back(task,std::ref(sync_point),i);}for(auto&t:threads){t.join();}return0;}
Task 2 is starting.
Task 1 is starting.
Task 0 is starting.
Task 3 is starting.
Task 4 is starting.
Task 0 is waiting at the barrier.
Task 1 is waiting at the barrier.
Task 2 is waiting at the barrier.
Task 3 is waiting at the barrier.
Task 4 is waiting at the barrier.
Task 4 has passed the barrier.
Task 3 has passed the barrier.
Task 2 has passed the barrier.
Task 1 has passed the barrier.
Task 0 has passed the barrier.
#include<iostream>#include<latch>#include<thread>#include<vector>#include<syncstream>voidtask(std::latch&sync_point,intid){std::osyncstream(std::cout)<<"Task "<<id<<" is starting.\n";// 模拟工作std::this_thread::sleep_for(std::chrono::milliseconds(100*id));std::osyncstream(std::cout)<<"Task "<<id<<" is done.\n";sync_point.count_down();}intmain(){constintnum_threads=5;std::latchsync_point(num_threads);std::vector<std::thread>threads;for(inti=0;i<num_threads;++i){threads.emplace_back(task,std::ref(sync_point),i);}sync_point.wait();// 等待所有线程完成for(auto&t:threads){t.join();}std::osyncstream(std::cout)<<"All tasks have completed.\n";return0;}
Task 0 is starting.
Task 1 is starting.
Task 2 is starting.
Task 3 is starting.
Task 0 is done.
Task 4 is starting.
Task 1 is done.
Task 2 is done.
Task 3 is done.
Task 4 is done.
All tasks have completed.