is there any way to wakeup multiple threads at the same time in c/c++ - c++

well, actually, I'm not asking the threads must "line up" to work, but I just want to notify multiple threads. so I'm not looking for barrier.
it's kind of like the condition_variable::notify_all(), but I don't want the threads wakeup one-by-one, which may cause starvation(also the potential problem in multiple semaphore post operation). it's kind of like:
std::atomic_flag flag{ATOMIC_FLAG_INIT};
void example() {
if (!flag.test_and_set()) {
// this is the thread to do the job, and notify others
do_something();
notify_others(); // this is what I'm looking for
flag.clear();
} else {
// this is the waiting thread
wait_till_notification();
do_some_other_thing();
}
}
void runner() {
std::vector<std::threads>;
for (int i=0; i<10; ++i) {
threads.emplace_back([]() {
while(1) {
example();
}
});
}
// ...
}
so how can I do this in c/c++ or maybe posix API?
sorry, I didn't make this question clear enough, I'd add some more explaination.
it's not thunder heard problem I'm talking about, and yes, it's the re-acquire-lock that bothers me, and I tried shared_mutex, there's still some problem.
let me split the threads to 2 parts, 1 as leader thread, which do the writing job, the others as worker threads, which do the reading job.
but actually they're all equal in programme, the leader thread is the thread that 1st got access to the job( you can take it as the shared buffer is underflowed for this thread). once the job is done, the other workers just need to be notified that them have the access.
if the mutex is used here, any thread would block the others.
to give an example: the main thread's job do_something() here is a read, and it block the main thread, thus the whole system is blocked.
unfortunatly, shared_mutex won't solve this problem:
void example() {
if (!flag.test_and_set()) {
// leader thread:
lk.lock();
do_something();
lk.unlock();
flag.clear();
} else {
// worker thread
lk.shared_lock();
do_some_other_thing();
lk.shared_unlock();
}
}
// outer loop
void looper() {
std::vector<std::threads>;
for (int i=0; i<10; ++i) {
threads.emplace_back([]() {
while(1) {
example();
}
});
}
}
in this code, if the leader job was done, and not much to do between this unlock and next lock (remember they're in a loop), it may get the lock again, leave the worker jobs not working, which is why I call it starve earlier.
and to explain the blocking in do_something(), I don't want this part of job takes all my CPU time, even if the leader's job is not ready (no data arrive for read)
and std::call_once may still not be the answer to this. because, as you can see, the workers must wait till the leader's job finished.
to summarize, this is actually a one-producer-multi-consumer problem.
but I want the consumers can do the job when the product is ready for them. and any can be the producer or consumer. if any but the 1st find the product has run out, the thread should be the producer, thus others are automatically consumer.
but unfortunately, I'm not sure if this idea would work or not

it's kind of like the condition_variable::notify_all(), but I don't want the threads wakeup one-by-one, which may cause starvation
In principle it's not waking up that is serialized, but re-acquiring the lock.
You can avoid that by using std::condition_variable_any with a std::shared_lock - so long as nobody ever gets an exclusive lock on the std::shared_mutex. Alternatively, you can provide your own Lockable type.
Note however that this won't magically allow you to concurrently run more threads than you have cores, or force the scheduler to start them all running in parallel. They'll just be marked as runnable and scheduled as normal - this only fixes the avoidable serialization in your own code.

It sounds like you are looking for call_once
#include <mutex>
void example()
{
static std::once_flag flag;
bool i_did_once = false;
std::call_once(flag, [&i_did_once]() mutable {
i_did_once = true;
do_something();
});
if(! i_did_once)
do_some_other_thing();
}
I don't see how your problem relates to starvation. Are you perhaps thinking about the thundering herd problem? This may arise if do_some_other_thing has a mutex but in that case you have to describe your problem in more detail.

Related

Deadlock with boost::condition_variable

I am a bit stuck with the problem, so it is my cry for help.
I have a manager that pushes some events to a queue, which is proceeded in another thread.
I don't want this thread to be 'busy waiting' for events in the queue, because it may be empty all the time (as well as it may always be full).
Also I need m_bShutdownFlag to stop the thread when needed.
So I wanted to try a condition_variable for this case: if something was pushed to a queue, then the thread starts its work.
Simplified code:
class SomeManager {
public:
SomeManager::SomeManager()
: m_bShutdownFlag(false) {}
void SomeManager::Initialize() {
boost::recursive_mutex::scoped_lock lock(m_mtxThread);
boost::thread thread(&SomeManager::ThreadProc, this);
m_thread.swap(thread);
}
void SomeManager::Shutdown() {
boost::recursive_mutex::scoped_lock lock(m_mtxThread);
if (m_thread.get_id() != boost::thread::id()) {
boost::lock_guard<boost::mutex> lockEvents(m_mtxEvents);
m_bShutdownFlag = true;
m_condEvents.notify_one();
m_queue.clear();
}
}
void SomeManager::QueueEvent(const SomeEvent& event) {
boost::lock_guard<boost::mutex> lockEvents(m_mtxEvents);
m_queue.push_back(event);
m_condEvents.notify_one();
}
private:
void SomeManager::ThreadProc(SomeManager* pMgr) {
while (true) {
boost::unique_lock<boost::mutex> lockEvents(pMgr->m_mtxEvents);
while (!(pMgr->m_bShutdownFlag || pMgr->m_queue.empty()))
pMgr->m_condEvents.wait(lockEvents);
if (pMgr->m_bShutdownFlag)
break;
else
/* Thread-safe processing of all the events in m_queue */
}
}
boost::thread m_thread;
boost::recursive_mutex m_mtxThread;
bool m_bShutdownFlag;
boost::mutex m_mtxEvents;
boost::condition_variable m_condEvents;
SomeThreadSafeQueue m_queue;
}
But when I test it with two (or more) almost simultaneous calls to QueueEvent, it gets locked at the line boost::lock_guard<boost::mutex> lockEvents(m_mtxEvents); forever.
Seems like the first call doesn't ever release lockEvents, so all the rest just keep waiting for its freeing.
Please, help me to find out what am I doing wrong and how to fix this.
There's a few things to point out on your code:
You may wish to join your thread after calling shutdown, to ensure that your main thread doesn't finish before your other thread.
m_queue.clear(); on shutdown is done outside of your m_mtxEvents mutex lock, meaning it's not as thread safe as you think it is.
your 'thread safe processing' of the queue should be just taking an item off and then releasing the lock while you go off to process the event. You've not shown that explicitly, but failure to do so will result in the lock preventing items from being added.
The good news about a thread blocking like this, is that you can trivially break and inspect what the other threads are doing, and locate the one that is holding the lock. It might be that as per my comment #3 you're just taking a long time to process an event. On the other hand it may be that you've got a dead lock. In any case, what you need is to use your debugger to establish exactly what you've done wrong, since your sample doesn't have enough in it to demonstrate your problem.
inside ThreadProc, while(ture) loop, the lockEvents is not unlocked in any case. try put lock and wait inside a scope.

Is this threadpool usage safe?

I'm posting several jobs to a threadpool and then waiting for it to finish. I'm wondering if I've missed something here, since occasionally my worker threads seem to freeze.
My main thread start the workers like this:
numJobsPosted = 0;
for(auto entry : list)
{
numJobsPosted++;
threadPool->post(std::bind(&Controller::workerFunc, this, entry));
}
std::unique_lock<std::mutex> lock(m_workerLock);
while(numJobsPosted > 0)
{
m_workerCondition.wait(lock);
}
Now my workerFunc looks something like this:
void Controller::workerFunc(Entry entry)
{
// do some work with entry
// notify finished
numJobsPosted--;
if(numJobsPosted <= 0)
{
// does the look need to be around the numJobsPosted-- ?
std::unique_lock<std::mutex> locker(m_workerLock);
m_workerCondition.notify_one();
}
}
Is the above code safe, or do I need to put the lock around the decrement operator?
This may depend on details of your thread pool's inner logic or setup (e.g. if you have a single thread, so jobs are actually run sequentially), but assuming that numJobsPosted is an int or similar built-in type, your code isn't thread-safe.
This line in workerFunc:
numJobsPosted--;
could very well be the subject of a race condition if it gets executed by several jobs concurrently.
Also, I'm not sure what your threadpool's post function does precisely, but if it dispatches the worker function to a thread right away and some of the worker functions can return immediately, you have another possible race condition between this line in your main thread code:
numJobsPosted++;
and this line in workerFunc:
numJobsPosted--;
To make it safe, you can for instance make numJobsPosted atomic, e.g. declare it like this (in C++11):
#include <atomic>
std::atomic_int numJobsPosted;
Making your workerFunc something like this:
void Controller::workerFunc(Entry entry)
{
// do some work with entry
// notify finished
{
std::unique_lock<std::mutex> locker(m_workerLock);
numJobsPosted--;
if(numJobsPosted <= 0)
{
m_workerCondition.notify_one();
}
}
}
may solve the first race condition case, but not the second.
(Also, I don't really understand the logic around the manipulation and testing you're doing on numJobsPosted, but I think that's beside the point of your question)

Thread synchronisation: Wait on two bool variables

I want to wait for two bool variables to be true in one thread. They are changed in different places. I can use boost in my project, but not C++11.
I did find Info on how to use mutexes and condition variables, but im not sure if its possible to wait for two mutexes.
This is some pseudocode of my program.
bool job1_dataready, job2_dataready;
//t1:
void job1()
{
//do stuff
job1_dataready = true;
}
//t2:
void job2()
{
//do stuff
job2_dataready= true;
}
main()
{
boost::thread t1(job1);
boost::thread t1(job2);
if(job1_dataready&& job2_dataready)
{
//do stuff with data from both jobs
}
}
from what I see, you don't need bool variables, use std::thread::join instead:
main() {
std::thread t1(job1);
std::thread t1(job2);
t1.join();
t2.join();
// do jobs after threads t1 and t2 finish working
}
you would block on the condition variable, check your boolean values when woken, and either go back to waiting or continue processing. Your threads will signal the condition variable after they have set the boolean flag. All with appropriate mutex locking of course. You can wait on an infinite number of conditions, just check when woken after blocking on the condition.
In simple situations like this, you wait on two mutexes simply by locking them in order. First you lock the mutex from thread 1, then the mutex from thread 2. If thread 2 would finish before thread 1, the main thread would simply not block when locking mutex 2.
However, note that this is an answer you your question, but not a solution to your problem. The reason is that you have a race condition with the mutex: the main thread might lock the mutex before the worker thread even starts. So, while Andrei R.s response (std::thread::join) isn't a direct answer, it is the correct solution.
If you plan to set your two bools just before the respective threads terminate, then Andrei R.'s solution of just joining the two threads is definitely the best way to go. However, if your threads actually continue working after the dataready points are reached, and are thus not terminating yet, you need a different approach. In that case, you could use two std::future/std::promise objects, which would look something like this:
std::promise<bool> job1_dataready, job2_dataready;
//t1:
void job1()
{
//do stuff
job1_dataready.set_value(true); // The value doesn't actually matter
//do more stuff
}
//t2:
void job2()
{
//do stuff
job2_dataready.set_value(true);
//do more stuff
}
main()
{
std::future<bool> job1_future = job1_dataready.get_future();
std::future<bool> job2_future = job2_dataready.get_future();
boost::thread t1(job1);
boost::thread t2(job2);
job1_future.wait();
job2_future.wait();
if (job1_future.get() && job2_future.get()) // True unless something was aborted
{
//do stuff with data from both jobs
}
}

How to block until a condition is met

I wanted to know what the best way is to block a method until a condition becomes true.
Example:
class DoWork
{
int projects_completed;
public:
.....
void WaitForProjectsCompleted()
{
---->//How do I block until projects_completed == 12;
}
};
I want it to be used as such
class foo
{
....
void someMethod()
{
DoWork work;
work.WaitForProjectsCompleted();//This should block
}
}
Assuming that there's another thread that's actually going to do something here, an easy thing to use is a std::condition_variable:
std::condition_variable cv;
std::mutex mtx;
void WaitForProjectsCompleted() {
std::unique_lock<std::mutex> lk(mtx);
cv.wait(lk, [this]{
return projects_completed >= 12;
});
}
Where somewhere else, some other member function might do:
void CompleteProject() {
{
std::lock_guard<std::mutex> lk(mtx);
++projects_completed;
}
cv.notify_one(); // let the waiter know
}
If projects_completed is atomic, you could instead just spin:
void WaitForProjectsCompleted() {
while (projects_completed < 12) ;
}
That would work fine too.
Condition variables are an excellent synchronization primitive, and in my personal experience it is the tool I respond with to 95% of synchs/threading situations.
If you don't have C++11 available you can use boost::condition_variable.
In which case you won't have the wait version with a predicate (because no lambdas in C++03). So you absolutely need to remember to loop over your condition check. As explained in the docs:
boost::unique_lock<boost::mutex> lock(mut);
while (projects_completed < 12)
{
wait(lock);
}
c.f.:
http://www.boost.org/doc/libs/1_58_0/doc/html/thread/synchronization.html#thread.synchronization.condvar_ref
That's because you get no guarantee that the condition is fulfilled after a notification, particularly because the lock can be acquired by another thread in the interstice between unlock and notify. Also a spurious wake up could happen.
I also wrote an article about it:
http://www.gamedev.net/page/resources/_/technical/general-programming/multithreading-r3048
Also if you use timed_wait (and I recommend it as it often mitigates priority inversion), another trap not to fall into is the timeout, because of the loop you cannot use a relative timeout (like 2 seconds) you need an absolute system time determined before entering the loop.
boost makes it very clean with this technique:
system_time const timeout = get_system_time() + posix_time::seconds(2);
About the spin lock pattern proposed by Barry, I would not recommend it, unless you are in a real time environment, like playstation 3/4 or equivalent. Or unless you are sure it won't last for more than a few seconds.
By using spin locking you waste power, and you don't leave chance for CPU to enter sleep states (c.f intel speed step).
This also has consequences on fairness and scheduling, as explained on wikipedia:
https://en.wikipedia.org/wiki/Spinlock
Finally if you don't have boost, since windows Vista we get natives Win32 functions:
SleepConditionVariableCS
https://msdn.microsoft.com/en-us/library/windows/desktop/ms686301(v=vs.85).aspx

(C++ Threads): Creating worker threads that will be listening to jobs and executing them concurrently when wanted

Suppose we have two workers. Each worker has an id of 0 and 1. Also suppose that we have jobs arriving all the time, each job has also an identifier 0 or 1 which specifies which worker will have to do this job.
I would like to create 2 threads that are initially locked, and then when two jobs arrive, unlock them, each of them does their job and then lock them again until other jobs arrive.
I have the following code:
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
struct job{
thread jobThread;
mutex jobMutex;
};
job jobs[2];
void executeJob(int worker){
while(true){
jobs[worker].jobMutex.lock();
//do some job
}
}
void initialize(){
int i;
for(i=0;i<2;i++){
jobs[i].jobThread = thread(executeJob, i);
}
}
int main(void){
//initialization
initialize();
int buffer[2];
int bufferSize = 0;
while(true){
//jobs arrive here constantly,
//once the buffer becomes full,
//we unlock the threads(workers) and they start working
bufferSize = 2;
if(bufferSize == 2){
for(int i = 0; i<2; i++){
jobs[i].jobMutex.unlock();
}
}
break;
}
}
I started using std::thread a few days ago and I'm not sure why but Visual Studio gives me an error saying abort() has been called. I believe there's something missing however due to my ignorance I can't figure out what.
I would expect this piece of code to actually
Initialize the two threads and then lock them
Inside the main function unlock the two threads, the two threads will do their job(in this case nothing) and then they will become locked again.
But it gives me an error instead. What am I doing wrong?
Thank you in advance!
For this purpose you can use boost's threadpool class.
It's efficient and well tested. opensource library instead of you writing newly and stabilizing it.
http://threadpool.sourceforge.net/
main()
{
pool tp(2); //number of worker threads-currently its 2.
// Add some tasks to the pool.
tp.schedule(&first_task);
tp.schedule(&second_task);
}
void first_task()
{
...
}
void second_task()
{
...
}
Note:
Suggestion for your example:
You don't need to have individual mutex object for each thread. Single mutex object lock itself will does the synchronization between all the threads. You are locking mutex of one thread in executejob function and without unlocking another thread is calling lock with different mutex object leading to deadlock or undefined behaviour.
Also since you are calling mutex.lock() inside whileloop without unlocking , same thread is trying to lock itself with same mutex object infinately leading to undefined behaviour.
If you donot need to execute threads parallel you can have one global mutex object can be used inside executejob function to lock and unlock.
mutex m;
void executeJob(int worker)
{
m.lock();
//do some job
m.unlock();
}
If you want to execute job parallel use boost threadpool as I suggested earlier.
In general you can write an algorithm similar to the following. It works with pthreads. I'm sure it would work with c++ threads as well.
create threads and make them wait on a condition variable, e.g. work_exists.
When work arrives you notify all threads that are waiting on that condition variable. Then in the main thread you start waiting on another condition variable work_done
Upon receiving work_exists notification, worker threads wake up, and grab their assigned work from jobs[worker], they execute it, they send a notification on work_done variable, and then go back to waiting on the work_exists condition variable
When main thread receives work_done notification it checks if all threads are done. If not, it keeps waiting till the notification from last-finishing thread arrives.
From cppreference's page on std::mutex::unlock:
The mutex must be unlocked by all threads that have successfully locked it before being destroyed. Otherwise, the behavior is undefined.
Your approach of having one thread unlock a mutex on behalf of another thread is incorrect.
The behavior you're attempting would normally be done using std::condition_variable. There are examples if you look at the links to the member functions.