Qt moveToThread works only the first time - c++

I'm creating an application performing an infinity task, so I decided to manage it with a QThread. On specific condition, this thread should spawns a temporary therad in order to perform some computation. The problem is that this works only the first time, while the second time I get this error:
QObject::moveToThread: Current thread (0xd29078) is not the object's thread (0x6e000df0).
Cannot move to target thread (0x6e002c68)
In the main I initialized the class and moved it in a QThread.
AccelerometerBuffer accBuffer;
QThread *accelerometerThread = new QThread;
accelerometerThread->setObjectName("AccelerometerThread");
accelerometerThread->setParent(&accBuffer);
accBuffer.moveToThread(accelerometerThread);
QObject::connect(accelerometerThread,SIGNAL(started()),&accBuffer,SLOT(readAccelerationData()));
QObject::connect(accelerometerThread,SIGNAL(finished()),accelerometerThread,SLOT(deleteLater()));
accelerometerThread->start();
In readAccelerationData, after condition, I should call another SLOT (saveData()) in the AccelerometerBuffer class and so the temporary thread should be spawned by the accelerometerThread.
if(condition){
QThread* thread = new QThread;
QThread::currentThread()->moveToThread(thread);
connect(thread,SIGNAL(started()),QThread::currentThread()->parent(),SLOT(saveData()));
connect(thread,SIGNAL(finished()),thread,SLOT(deleteLater()));
thread->start();
}
The first time that the condition occurs, everything works fine, saveData is correctly executed.
The following times, instead, I get the error and I don't understand the reason.

You can only moveToThread from the owning thread. As soon as your move to another thread, the same call will no longer be able to do anything.
From https://doc.qt.io/qt-5/qobject.html#moveToThread
Warning: This function is not thread-safe; the current thread must be same as the current thread affinity. In other words, this function can only "push" an object from the current thread to another thread, it cannot "pull" an object from any arbitrary thread to the current thread.

Related

Is QThread::quit usabled from within the running thread

So I have the following situation:
I have a QThread that runs an eventloop (i.e. no custom run function). To stop the thread, I send a signal to a worker in that thread. This worker then does cleanups etc and at some point is done and quits the thread.
The problem I am facing right now is: If I invoke the workers stop method and then immediatly wait for the thread to finish it will never do so because the workers done signal does not get processed. Code:
class Worker {
signals:
void done();
public slots:
void stop() {
//dummy code to illustrate what happens here:
QTimer::singleShot(3000, this, &Worker::done);
}
};
// in the main thread
auto thread = new QThread();
auto worker = new Worker();
worker->moveToThread(thread);
connect(worker, &Worker::done, thread, &QThread::quit); //implicitly a queued connection
// ...
QMetaObject::invokeMethod(worker, "stop", Qt::QueuedConnection);
thread->wait(); //blocks here forever, because the connect is queued
Now reason the problem is obvious - Because I block on the main thread the slot can never be invoked (because queued connection) and thus quit is never called. However, if I simply call QThread::quit (or QThread::exit) directly from the worker (or use a DirectConnection) then there is no problem anymore because the eventloop of the main thread is no longer required to process the event.
So the actual question here is: Is that allowed? Can I call QThread::quit from within the actual thread? Or can this create Race conditions, deadlocks and other problems like that. The documentation does not mark the method as threadsafe - but the thread that is managed by QThread might be an exception.
If you look in the file src/corelib/thread/qthread.cpp in the Qt source folder, you can see how quit() is implemented:
void QThread::quit()
{ exit(); }
.... and QThread::exit() is definitely intended to be called from within the thread itself. So the answer is yes, it's fine to call quit() from within the QThread's thread (although it might be a bit more usual to just call QThread::exit() directly instead).
Can I call QThread::quit from within the actual thread?
The question is actually backwards!
Since this method controls the event loop, and the event loop most definitely runs on the thread, the default assumption is that it's not a thread-safe method and thus can only be called from within the thread, since it controls a QEventLoop instance instantiated via QThread::run. That event loop, and its event dispatcher, are QObjects and most definitely have their thread() equal to the QThread instance in question.
But that wouldn't make QThread very useful, and thus QAbstractEventDispatcher::exit, and thus QEventLoop::quit and QThread::quit, are indeed thread-safe methods - you can call them from wherever, including from threads other than the one where the event loop lives. Both the event loop and thread's methods take extra precautions to protect their state from races, so the "and thus" part a few sentences ago is hand-wavey a bit.

When does a boost::thread terminate ? How to manage boost::threads?

I have a class that handles zmq messages. If a message is received the class notifies its observer. This observer than creates a boost::thread which resolves the received zmq message. After the message is resolved the observer starts another thread which than executes the resolved command.
So there is one observer which creates a thread for each incoming message. How do I ensure that the created threads are safely destroyed after they resolved the message ? Also what happens with the thread that is started within the resolver thread. That thread also has to be destroyed safely in the end.
I think there is a simple solution for this but I lack the experience with multi-threading and don't no what to google ...
Edit:
Do I even have to care about threads when they returned a value by themselves ?
Threads can be detached or joined. If you join, your main thread is going to block until its complete. If you detach, your thread runs until its finished or your application terminates. Assuming the latter isn't going to happen, this is fine.
Regarding boost::threads specifically (by the way, do you have access to std::thread - introduced C++11)..
When the boost::thread object that represents a thread of execution is destroyed the thread becomes detached. Once a thread is detached, it will continue executing until the invocation of the function or callable object supplied on construction has completed, or the program is terminated. A thread can also be detached by explicitly invoking the detach() member function on the boost::thread object. In this case, the boost::thread object ceases to represent the now-detached thread, and instead represents Not-a-Thread.
In order to wait for a thread of execution to finish, the join() or timed_join() member functions of the boost::thread object must be used. join() will block the calling thread until the thread represented by the boost::thread object has completed. If the thread of execution represented by the boost::thread object has already completed, or the boost::thread object represents Not-a-Thread, then join() returns immediately. timed_join() is similar, except that a call to timed_join() will also return if the thread being waited for does not complete when the specified time has elapsed.
As an aside, unless this application is for a small number of connections, think a bit about whether you really need a thread per request. There is some overhead (10s of microsends and by default sometimes between 1-2MB of memory).

Confusion regarding QThread, QObject, Thread Affinity and Event Loop

I was going through the links
You are doing it wrong
Using QThread in right way Part1
Using QThread in right way Part2
I got confused by some statements. In the first link, it says that
all of the functions in QThread were written and intended to be called from the creating thread, not the thread that QThread starts.
while it suggests to use moveToThread to move an object to new thread, instead of subclassing QThread. My question is:
The default implementation of run method calls exec, which creates an event loop, and when an object's thread affinity is changed using moveToThread, all the slots will be executed in the new thread, not on the creating thread, which is contradictory with the aforementioned intended use. Am I missing something?
Second question:
In the third link it is said
event queue is belong to thread instead of event loop, and it’s shared by all the event loops running in this thread.
My question is how there can be more than one event loop in a single thread ? What I understand is, event-loop loop through the event-queue, until exit/terminate is called, and processes each event arrives on that queue. If this is true, one loop will never end (unless exit/terminate is called), how another can begin? Any sample code demonstrating it will be highly appreciated.
"which is contradictory with the aforementioned intended use. Am I missing something?"
Yes, I think you're misunderstanding the concept of thread affinity (the thread on which an object is running).
Let's take an example with minimal code: -
QThread* pThread = new QThread; // QThread on the main thread
MyObject* myObj = new MyObject; // MyObject on the main thread
myObj->moveToThread(pThread); // MyObject on the new thread, controlled by pThread
pThread->start(); // pThread instance is still on the main thread
Assuming this code has been created from an object whose thread affinity is the main thread, such as QMainWindow, the thread object pThread is running on the main thread; it's thread affinity is the main thread.
In contrast, the QObject derived MyObject instance, myObj, has been moved to the new thread pThread. So, the thread affinity of myObj is now the new thread.
The "functions written for QThread" are still called directly from the main thread, as that's where it's running.
Think of QThread as a thread controller object, rather than the thread itself. This is one of the reasons why it is often discouraged to inherit from QThread, unless you want to change how QThread manages the underlying thread.
how there can be more than one event loop in a single thread ?...
I've not used this directly myself, but I'll try to explain this as I understand it. Perhaps someone else will be able to correct or confirm this. From the Qt Documentation for QEventLoop, it states: -
At any time, you can create a QEventLoop object and call exec() on it to start a local event loop.
The signature from QEventLoop exec is: -
int QEventLoop::exec ( ProcessEventsFlags flags = AllEvents )
So if you pass in a set of flags, only these events would be handled. Now, as calling exec() starts the processing of events until exit() is called, you can create a local event loop that lets your program wait until one or more specific events occur.
A second event loop is a local event loop within the main event loop, but as each event loop can process the whole event queue, which is shared by all event loops in a thread, it can be used to override event handling from the main event loop.
If you conceptualise an event loop as doing something like this (pseudo code): -
QList<QEvent*> eventList;
while(!stop)
{
// handle events in eventList
}
A 2nd event loop would then do this: -
bool bStop = false;
QList<QEvent*> eventList;
while(!bStop)
{
// handle events in eventList
...
...
// Inner event loop
bool bStop = false;
while(!bStop)
{
// handle events in eventList
}
}

What is the use of QThread.wait() function?

I have stumbled upon this problem, as others haves:
QThread won't stop / does not process a signal
QThread - Using a slot quit() to exit the thread
The problem is that I want to have a worker thread started, do some job (which involves sending signals to other threads in my code, and receiving signals asynchronously) and then exit. But I want this thread to be synchronized with the code that is starting it. In other words, I want the execution in the code which creates the worker thread to be halted until the worker thread is done its job.
But it seems this is not possible in Qt. The reason is that the worker's QThread.quit() slot cannot be signaled from within the thread itself. The event loop which listens for signals to this slot, should reside in the same thread that created the worker thread. This means the creating thread should not be blocked, otherwise the worker thread never stops.
Which brings me to my question, that what is the point of QThread.wait() then? I think this function should just be stuck at the end of the program to make sure all the threads have exited, but it cannot actually be used to synchronize threads, at least it cannot be used to synchronize a worker thread, with the thread that created it. Because if the QThread.wait() is called from the creating thread, it blocks its event loop, which will block the worker thread's interface, which will prevent it from ever exiting.
Am I missing something?
I thought I need to add a code snippet:
for (auto i = myVector.begin(); i < myVector.end(); ++i)
{
// 5-line best practice creation for the thread
QThread* workerThread = new QThread;
MyWorkerObject* workerObject = new MyWorkerObject(0);
workerObject->moveToThread(workerThread);
QObject::connect(workerThread, SIGNAL(started()), workerObject, SLOT(init()));
QObject::connect(workerThread, SIGNAL(finished()), workerObject, SLOT(deleteLater()));
// Stop mechanism
QObject::connect(workerObject, SIGNAL(finished()), workerThread, SLOT(quit()));
// Start mechanism
wokerThread->start();
// Invoking the work
QMetaObject::invokeMethod(workerObject, "StartYourJob", Qt::QueuedConnection, Q_ARG(SomeType, *i));
// Synchronization
workerThread->wait();
delete wokerThread;
}
I finally found my answer here:
http://comments.gmane.org/gmane.comp.lib.qt.user/6090
In short, if QThread::quit() is invoked as a slot, the event loop handler of the creating thread will deal with it, which is not what I want.
I should call it directly. So when the workerObject finishes its job, instead of sending a signal (which has to pass through the blocked creating thread), it should directly call its container's quit:
this->thread()->quit();
This would be the exit point of the workerObject. Now there is no need for the stop mechanism and these lines can be eliminated from the code.
// Stop mechanism
QObject::connect(workerObject, SIGNAL(finished()), workerThread, SLOT(quit()));
Does anybody see any problem with this approach?
The purpose of threads is to allow processes to run concurrently (at the same time!), so if you're just creating a thread to do work and waiting on the current thread, you don't need to be using a new thread.
To answer your question of the purpose of QThread::wait(), the Qt documentation states that it is similar to the POSIX function pthread_join. A quick search on pthread_join reveals this link, which states the rationale is as follows: -
The pthread_join() function is a convenience that has proven useful in
multi-threaded applications. It is true that a programmer could
simulate this function if it were not provided by passing extra state
as part of the argument to the start_routine(). The terminating thread
would set a flag to indicate termination and broadcast a condition
that is part of that state; a joining thread would wait on that
condition variable. While such a technique would allow a thread to
wait on more complex conditions (for example, waiting for multiple
threads to terminate), waiting on individual thread termination is
considered widely useful. Also, including the pthread_join() function
in no way precludes a programmer from coding such complex waits. Thus,
while not a primitive, including pthread_join() in this volume of
POSIX.1-2008 was considered valuable.
The pthread_join() function provides a simple mechanism allowing an
application to wait for a thread to terminate. After the thread
terminates, the application may then choose to clean up resources that
were used by the thread. For instance, after pthread_join() returns,
any application-provided stack storage could be reclaimed.
The pthread_join() or pthread_detach() function should eventually be
called for every thread that is created with the detachstate attribute
set to PTHREAD_CREATE_JOINABLE so that storage associated with the
thread may be reclaimed.
The interaction between pthread_join() and cancellation is
well-defined for the following reasons:
The pthread_join() function, like all other non-async-cancel-safe
functions, can only be called with deferred cancelability type.
Cancellation cannot occur in the disabled cancelability state.
Thus, only the default cancelability state need be considered. As
specified, either the pthread_join() call is canceled, or it succeeds,
but not both. The difference is obvious to the application, since
either a cancellation handler is run or pthread_join() returns. There
are no race conditions since pthread_join() was called in the deferred
cancelability state.
If an implementation detects that the value specified by the thread
argument to pthread_join() does not refer to a joinable thread, it is
recommended that the function should fail and report an [EINVAL]
error.
If an implementation detects that the value specified by the thread
argument to pthread_join() refers to the calling thread, it is
recommended that the function should fail and report an [EDEADLK]
error.
If an implementation detects use of a thread ID after the end of its
lifetime, it is recommended that the function should fail and report
an [ESRCH] error.
QThread::wait() is not what you need. This function is exactly what you mentioned, it waits for thread termination.
bool QThread::wait ( unsigned long time = ULONG_MAX )
Blocks the thread until either of these conditions is met:
The thread associated with this QThread object has finished execution (i.e. when it
returns from run()). This function will return true if the thread has finished. It also
returns true if the thread has not been started yet.
time milliseconds has elapsed. If time is ULONG_MAX (the default), then the wait will
never timeout (the thread must return from run()). This function will return false if the
wait timed out.
If you need to synchronize two threads (Your main thread and created thread) then I recommend using signals and slots to signal which one is ready (trigger a isReady bool) and have a while (!isReady) { sleep(1ms); processEvents(); } loop going. May not be the best way but should work.

Questions about implementing QThread in my application?

As suggested in this question, I am now trying to incorporate multithreading.
According to the links given by karlphillip, I understand that the documentation about subclassing QThread is not to be followed and to use moveToThread() as explained. Now I see that default implementation of QThread run() has only an exec() which must then be ended by calling quit() when worker thread has finished operations. I have a few questions now so that I understand things better:
QApplication* ptrApp=new QApplication(argc,argv);
QThread* th=new QThread;
MyClass* obj=new MyClass;
obj->moveToThread(th);
QObject::connect(th,SIGNAL(started()),obj,SLOT(someFunct()));
QObject::connect(obj,SIGNAL(over()),th,SLOT(quit()));
th->start();
//some GUI code in main thread here
return ptrApp->exec();
What happens if I continue to use someFunct() even after I emit over() from within someFunct()? Is it undefined behaviour or normal?
Which thread would obj now be associated with (while the rest of the code after emitting over() is still executing in someFunct)? My understanding is: it cannot be in th when I have quit() that thread... quit() will be queued until the exec() in the main thread executes it which will cause the exec() in run() of th to exit (I hope I am not making a mistake here). I assume that thread is no longer existent.
Once slot quit() for th is executed, is it safe to assume that the thread has indeed quit or should I further connect finished() signal of th to some slot to be absolutely sure?
It doesn't matter if the event loop is terminated, somefunct() will continue to run until it gives control back to the now extinct loop.
obj stays associated to the thread, so if a signal connected to one of its slots is emitted, the slot won't run but it will be queued for when/if the thread is restarted.
If the QThread object is deleted, obj->thread() returns 0, so I suppose this would be equivalent to calling obj->moveToThread(0) and according to the documentation:
If targetThread is zero, all event processing for this object and its children stops.
quit() terminates the event loop, then the finished() signal is emitted from the thread, and the thread terminates.
So, even when you receive the finished() signal, you shouldn't assume that the thread is finished yet. You can use QThread::wait from the main thread, after you receive that signal to ensure that.
If the thread is in the finishing state, the QThread destructor already calls wait, so you can safely delete the thread after the finished() signal (with deleteLater() to be even safer).
1. What happens if I continue to use someFunct() even after I emit over() from within someFunct()? Is it undefined behaviour or normal?
As you are using direct connections, emitting over will call directly the function quit, which stops the event loop and return from the exec in the thread run method. Which means someFunct() will not finish its execution and the objects inside it are either lost or in a partial modified state.
2. Which thread would obj now be associated with (while the rest of the code after emitting over() is still executing in someFunct)?
As said previously somefunct will not finish its execution. But I believe any objects associated with this thread will remain as such. I say I believe because there is no solid assertion anywhere, but it make sense the most. As mentioned in the doc, for these objects to send or receive events the thread must be started again....
3. Once slot quit() for th is executed, is it safe to assume that the thread has indeed quit or should I further connect finished() signal of th to some slot to be absolutely sure?
quit() terminates the event loop and return where exec() was called.
Notice that the object Qthread is not the thread. so until you enter exec(), it is the main thread which is running... As well as it is the main thread which runs after the exec.
Anyway these are some great questions...