C ++ holding multiple threads

I am new to C ++ (on Windows) and the thread, and I'm currently trying to find a solution to my problem using mutexes, semaphores, and events. I am trying to create a Barrier class with constructor and Enter method. The Barrier class with it, only the Enter method should hold any thread that goes into it until a series of threads reach this method. The number of threads waiting to receive it in the constructor. My problem is how can I use locks to create this effect? I need something like an inverse semaphore that contains threads until the count is reached, and not like regular semaphores that allow threads until the count is reached. Any ideas on how to do this would be great. Thanks, Netanel.

+4
source share
3 answers

May be:

In ctor, save the limit counter and create an empty semaphore.

When a thread calls Enter, first lock the mutex so that you can safely navigate inside. Include thread counting in the limit account. If the limit has not yet been reached, release the mutex and wait on the semaphore. If the limit is reached, report the [limit-1] semaphore once in the loop, reset the thread counter (ready for the next time), release the mutex and return from Enter (). Any threads waiting for the semaphore and now ready / executed should just return from their 'Enter' call.

The mutex prevents any released thread from starting from entering the system until all threads that called 'Enter' and waited were set and the barrier was reset.

+1
source

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.

+1
source

The pseudocode scheme may look like this:

 void Enter() { Increment counter (atomically or with mutex) if(counter >= desired_count) { condition_met = true; (protected if bool writes aren't atomic on your architecture) cond_broadcast(blocking_cond_var); } else { Do a normal cond_wait loop-plus-predicate-check (waiting for the broadcast and checking condition_met each iteration to protect for spurious wakeups). } } 
0
source

Source: https://habr.com/ru/post/1497092/


All Articles