barrier.cpp (967B)
1 #include <barrier> 2 #include <iostream> 3 #include <span> 4 #include <syncstream> 5 #include <thread> 6 #include <utility> 7 8 static unsigned phase; 9 10 void barrier_cb() 11 { 12 std::osyncstream{std::cout} << "Barrier: phase " << ++phase << "\n"; 13 } 14 15 void work(unsigned i, std::barrier<void(*)()>* b) 16 { 17 unsigned name = i; 18 19 while (i) 20 { 21 b->arrive_and_wait(); 22 std::osyncstream{std::cout} << name << ": doing phase " << phase << " work: " << i-- << "\n"; 23 } 24 b->arrive_and_drop(); 25 } 26 27 void do_works(std::span<unsigned> eyes) 28 { 29 phase = 0; 30 if (eyes.empty()) 31 return; 32 33 if (std::cmp_greater(eyes.size(), std::barrier<void(*)()>::max())) 34 std::terminate(); 35 36 auto n = static_cast<ptrdiff_t>(eyes.size()); 37 auto thread_eyes = eyes.subspan(0, n - 1); 38 std::barrier b{n, barrier_cb}; 39 std::jthread thrds[thread_eyes.size()], *t = thrds; 40 41 for (auto i : thread_eyes) 42 *t++ = std::jthread(work, i , &b); 43 44 work(eyes.back(), &b); 45 } 46 47 int main() 48 { 49 unsigned x[] = {1,2,4,3}; 50 do_works(x); 51 }