You can implement it with a condition variable.
Here is an example:
I declare 25 threads and start them by executing the WorkerThread function.
The condition I check for blocking / untying threads is the number of threads in the section is less than 2. (I added a few statements to prove what my code does).
My code just sleeps in the critical section and after reducing the number of threads in the critical section.
I also added a mutex so that cout has clean messages. # include # include # include # include # include # include # include / * assert * / using the std namespace;
std::mutex m; atomic<int> NumThreadsInCritialSection=0; int MaxNumberThreadsInSection=2; std::condition_variable cv; mutex coutMutex; int WorkerThread() { // Wait until main() sends data { std::unique_lock<std::mutex> lk(m); cv.wait(lk, []{return NumThreadsInCritialSection<MaxNumberThreadsInSection;}); } assert (NumThreadsInCritialSection<MaxNumberThreadsInSection); assert (NumThreadsInCritialSection>=0); NumThreadsInCritialSection++; { std::unique_lock<std::mutex> lk(coutMutex); cout<<"NumThreadsInCritialSection= "<<NumThreadsInCritialSection<<endl; } std::this_thread::sleep_for(std::chrono::seconds(5)); NumThreadsInCritialSection--; { std::unique_lock<std::mutex> lk(coutMutex); cout<<"NumThreadsInCritialSection= "<<NumThreadsInCritialSection<<endl; } cv.notify_one(); return 0; } int main() { vector<thread> vWorkers; for (int i=0;i<25;++i) { vWorkers.push_back(thread(WorkerThread)); } for (auto j=vWorkers.begin(); j!=vWorkers.end(); ++j) { j->join(); } return 0; }
Hope this helps, tell me if you have any questions, I can comment or change my code.
source share