Why is std::thread blocking execution? - c++

I want to have a class method running in a separate thread :
std::thread myThread(&Class::method, this);
myThread.join();
//Other events
While doing this, the other events occur only when the Class:method is over, not simultaneously.
What did I forget ?

You are calling .join() on the thread, which blocks until that thread has finished, to run things concurrently with that thread either call join() after everything else that you want to run concurrently has finished, or call detach() on the thread object instead
For example
auto th = std::thread{[]() { ... }};
do_something();
th.join();
Here in this example do_something() will run concurrently with the thread th, or you can call detach()
std::thread{[]() { ... }}.detach();
do_something();

This is what happens:
Start a thread and have it run &Class::method
std::thread myThread(&Class::method, this);
Wait until the thread has ended.
myThread.join();
Do other things in the curren thread
//Other events
As you can see, your myThread.join() pauses your current thread.
Do it like this instead:
std::thread myThread(&Class::method, this);
//Other events
myThread.join();
Alternatively; don't perform that join and call myThread.detach(); instead.

Related

C++ : How to use an std::condition_variable between UI thread & worker std::thread

I am trying to use an std::condition_variable from C++11 for a data transaction between between UI thread & worker thread.
Situation:
m_calculated_value is a value which calculated after a complex logic. This is required on a trigger of a event from the UI thread. UI thread calls MyClass::GetCalculatedValue to fetch the value of m_calculated_value which needs to be calculated by the worker thread function that is MyClass::ThreadFunctionToCalculateValue.
Code:
std::mutex m_mutex;
std::condition_variable m_my_condition_variable;
bool m_value_ready;
unsigned int m_calculated_value;
// Gets called from UI thread
unsigned int MyClass::GetCalculatedValue() {
std::unique_lock<std::mutex> lock(m_mutex);
m_value_ready = false;
m_my_condition_variable.wait(lock, std::bind(&MyClass::IsValueReady, this));
return m_calculated_value;
}
bool MyClass::IsValueReady() {
return m_value_ready;
}
// Gets called from an std::thread or worker thread
void MyClass::ThreadFunctionToCalculateValue() {
std::unique_lock<std::mutex> lock(m_mutex);
m_calculated_value = ComplexLogicToCalculateValue();
m_value_ready = true;
m_my_condition_variable.notify_one();
}
Problem:
But the problem is that m_my_condition_variable.wait never returns.
Question:
What am I doing wrong here?
Is it a correct approach to make UI thread wait on a condition variable signal from worker thread? How do I get out of a situation where the condition_variable never triggers due to an error in the worker thread function? Is there a way I can somehow use a timeout here?
Trying to understand how it works:
I see in many examples they use a while loop checking the state of a boolean variable around a condition_var.wait. Whats the point of loop around on a variable? Cant I expect m_my_condition_variable to return out of wait when notify_one is called from other thread ?
What is most likely to happen:
Your worker thread owns and holds the mutex until it's done with the calculation. The main thread has to wait until it can acquire the lock. The worker will signal the CV before it releases the lock (in the destructor), by which time no other thread that would want to wait on the condition variable could have been acquired the lock that it still occupied by the notifying thread. Therefore the other thread never got a chance to wait on the condition variable at the time it gets notified as it just managed to acquire the lock after the notification event took place, causing it to wait infinitely.
The solution would be to remove the lock-acquisition in MyClass::ThreadFunctionToCalculateValue(), it is not required there at all, or at least, shouldn't be.
But anyways, why do you want to re-invent the wheel? For such problems, std::future has been created:
auto future = std::async(std::launch::async, ComplexLogicToCalculateValue);
bool is_ready = future.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
auto result = future.get();
Here, you can easily define timeouts, you don't have to worry about condition_variables and alike.
Cant I expect m_my_condition_variable to return out of wait when notify_one is called from other thread ?
No, not exclusively. Spurious wakeups still may occur.
Take a look at this example here:
http://en.cppreference.com/w/cpp/thread/condition_variable
Changes to the code in question noted in comments in the example code below. You might want to consider using the same "handshake" as used in the cppreference.com example to synchronize when it's safe to calculate a new value (the UI thread has a wait / notify, the worker thread has a notify / wait).
Before condition variable wait, the lock needs to be locked. The wait will unlock, wait for a notify, then lock and with the predicate function, check for ready and if not ready (spurious wake up), repeat the cycle.
Before notify_one, the lock should be unlocked, else the wait gets woke up, but fails to get a lock (since it's still locked).
std::mutex m_mutex;
std::condition_variable m_my_condition_variable;
bool m_value_ready = false; // init to false
unsigned int m_calculated_value;
// Gets called from UI thread
unsigned int MyClass::GetCalculatedValue() {
std::unique_lock<std::mutex> lock(m_mutex);
m_my_condition_variable.wait(lock, std::bind(&MyClass::IsValueReady, this));
m_value_ready = false; // don't change until after wait
return m_calculated_value;
} // auto unlock after leaving function scope
bool MyClass::IsValueReady() {
return m_value_ready;
}
// Gets called from an std::thread or worker thread
void MyClass::ThreadFunctionToCalculateValue() {
std::unique_lock<std::mutex> lock(m_mutex);
m_calculated_value = ComplexLogicToCalculateValue();
m_value_ready = true;
lock.unlock(); // unlock before notify
m_my_condition_variable.notify_one();
}
or alternative:
// Gets called from an std::thread or worker thread
void MyClass::ThreadFunctionToCalculateValue() {
{ // auto unlock after leaving block scope
std::lock_guard<std::mutex> lock(m_mutex);
m_calculated_value = ComplexLogicToCalculateValue();
m_value_ready = true;
} // unlock occurs here
m_my_condition_variable.notify_one();
}

Is deadlock possible in this simple scenario?

Please see the following code:
std::mutex mutex;
std::condition_variable cv;
std::atomic<bool> terminate;
// Worker thread routine
void work() {
while( !terminate ) {
{
std::unique_lock<std::mutex> lg{ mutex };
cv.wait(lg);
// Do something
}
// Do something
}
}
// This function is called from the main thread
void terminate_worker() {
terminate = true;
cv.notify_all();
worker_thread.join();
}
Is the following scenario can happen?
Worker thread is waiting for signals.
The main thread called terminate_worker();
The main thread set the atomic variable terminate to true, and then signaled to the worker thread.
Worker thread now wakes up, do its job and load from terminate. At this step, the change to terminate made by the main thread is not yet seen, so the worker thread decides to wait for another signal.
Now deadlock occurs...
I wonder this is ever possible. As I understood, std::atomic only guarantees no race condition, but memory order is a different thing. Questions:
Is this possible?
If this is not possible, is this possible if terminate is not an atomic variable but is simply bool? Or atomicity has nothing to do with this?
If this is possible, what should I do?
Thank you.
I don't believe, what you describe is possible, as cv.notify_all() afaik (please correct me if I'm wrong) synchronizes with wait(), so when the worker thread awakes, it will see the change to terminate.
However:
A deadlock can happen the following way:
Worker thread (WT) determines that the terminate flag is still false.
The main thread (MT) sets the terminate flag and calls cv.notify_all().
As no one is curently waiting for the condition variable that notification gets "lost/ignored".
MT calls join and blocks.
WT goes to sleep ( cv.wait()) and blocks too.
Solution:
While you don't have to hold a lock while you call cv.notify, you
have to hold a lock, while you are modifying terminate (even if it is an atomic)
have to make sure, that the check for the condition and the actual call to wait happen while you are holding the same lock.
This is why there is a form of wait that performs this check just before it sends the thread to sleep.
A corrected code (with minimal changes) could look like this:
// Worker thread routine
void work() {
while( !terminate ) {
{
std::unique_lock<std::mutex> lg{ mutex };
if (!terminate) {
cv.wait(lg);
}
// Do something
}
// Do something
}
}
// This function is called from the main thread
void terminate_worker() {
{
std::lock_guard<std::mutex> lg(mutex);
terminate = true;
}
cv.notify_all();
worker_thread.join();
}

Terminate current thread in destructor

In a project we're creating multiple statemachines in a wrapper-class. Each wrapper runs in it's own thread. When the jobs is done, the wrapper-class destructor is being called, and in there we would like to stop the thread.
Though if we're using thread.join(), we get a deadlock (since it tries to join itself). We could somehow signal another thread, but that seems a bit messy.
Is there any way to properly terminate the thread in which a class is running in, upon object destruction?
thread.join() does not stop a thread. It waits for the thread to finish and then returns. In order to stop a thread you have to have some way of telling the thread to stop, and the thread has to check to see whether it's time to stop. One way to do that is with an atomic bool:
class my_thread {
public:
my_thread() : done(false) { }
~my_thread() { done = true; thr.join(); }
void run() { thread th(&my_thread::do_it, this); swap(th, thr); }
private:
void do_it() { while (!done) { /* ... */ } }
std::thread thr;
std::atomic<bool> done;
};
That's off the top of my head; not compiled, not tested.

Qt thread design producer consumer

The main thread is loading tasks into a queue.
A worker thread is dealing with these tasks.
My code is like this:
//Core subclass a QThread
Core::AddTask()
{ ...
mutex.lock();
tasks.append(task);
mutex.unlock();
start();//which calls the run function
}
Core::RefreshTask()
{ ...
mutex.lock();
tasks.clear();
mutex.unlock();
// Calculate the new tasks...
...
//foreach newly added task call
AddTask();
}
Core::run()
{ ...
while (1)
{
finish = false;
mutex.lock();
tasks.dequeue();
if (tasks.size() == 0)
finish = true;
mutex.unlock();
...
if (finish)
break;
}
}
However I found the worker thread failed to finish all the tasks because when the run function is being processed, it will not response to start() call.
Then in the situation that: the run function is processing the last task and in the sametime AddTask is being called, then its start() call will do nothing. And the run() function finish and ignore the task.
I know a signal/slot mechanism could solve the problem. But I am forced to use the old QThread::run() style multithreading...
Any suggestions how to properly write a producer consumer pattern in Qt?
I think you don't need call start() in Core::AddTask(). When you add new task to task list, you can send some kind of event message. It can be Qt signal, condition variable or something else.
Event loop works in separate thread and process tasks. If task list is empty, event loop waits for an event.

Unable to connect between QThread with finished() signal for multiple Qthread

I have a 3 QThreads invoking by one another (all inherited from QThread. I know some might suggest to use moveToThread, but just ignore this fact for now). The simplified code looks like following:
Thread1 class:
void
Thread1::run
{
// some execution
Thread2 t2 = new Thread2();
connect(t2,SIGNAL(finished),this,SLOT(onFinished));
t2->start();
while(!stop) // stop was initialized as false
{
this->msleep(10);
}
}
void Thread1::onFinished(){ stop = true; }
Thread2 class:
void
Thread2::run
{
// some execution
Thread3 t3 = new Thread3();
connect(t3,SIGNAL(finished),this,SLOT(onFinished));
t3->start();
while(!stop) // stop was initialized as false
{
this->msleep(10);
}
}
void Thread2::onFinished(){ stop = true; }
Thread3 class:
void
Thread3::run
{
// some execution
QMutexLocker ml(&mMutex);
}
When I have only two threads, it works perfectly fine (e.g. just thread2 and thread3). The onFinished() method seems not connecting with finished() signal properly anymore, after I moved to a three-threads scenario. The onFinished() in thread2 has ever been called. And I am pretty sure the execution of the thread3 has completed.
Can anybody tell me where I could have done wrong?
First of all you should note that the default connection type is Qt::AutoConnection. This means if signal is emitted from a different thread than the receiving object's thread, Qt::QueuedConnection is used. In this case: The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread. So you need an event loop.
It works with 2 threads because you probably have an event loop running in your main thread. In your case where you use only thread2 and thread3 objects, thread2 object will actually live in the main thread, while thread3 object will live in the thread managed by the thread2 object. So slots in thread2 object should work.
But in the case of 3 threads, thread1 object would live in the main thread, thread2 object would live in the thread managed by thread1 object, and because there is no running event loop there, the slot in thread2 object will never be executed.
You can call QThread::exec() in your QThread::run() function, but note that the slots will be executed in the thread where your QThread object lives in, not the thread it manages. Because of this you shouldn't use slots in QThread subclasses. You should create a QObject subclass and move it to a thread.
Another option is to use Qt::DirectConnection for the connection type, when you connect your signals to slots.