This article detailing the "proper" use of QThread says
By the way, one extremely important thing to note here is that you should NEVER allocate heap objects (using new) in the constructor of the QObject class as this allocation is then performed on the main thread and not on the new QThread instance, meaning that the newly created object is then owned by the main thread and not the QThread instance. This will make your code fail to work. Instead, allocate such resources in the main function slot such as process() in this case as when that is called the object will be on the new thread instance and thus it will own the resource.
I understand the first part that the allocation of heap objects (and thus running a constructor) happens in the thread that created the QObject. Only after that it is pushed to the QThread using QThread::moveToThread.
However I don't quite understand the ownership issue mentioned, specifically
meaning that the newly created object is then owned by the main thread
It certainly is not referring standard ownership of resources because in Qt that can be easily controlled by parent-children mechanism.
Does it mean underlying memory management mechanisms of multithreading (or QThread although that is just a wrapper of OS' thread implementation as far as I know)? As in that there is a different "memory segment/cache" for each thread where its resources are stored?
If that is the case I could see the problem but I cannot find the full answer or explanation. Thanks!
It's referring to the fact that QObjects live in certain threads -- by default, the thread that created them. "Live" refers to the fact that QObject isn't reentrant nor thread safe: a QObject can be used only from the thread it lives in.
The advice is wrong, though. It's perfectly safe to do
class Foo : public QObject {
Q_OBJECT
Foo() {
m_suboject = new Bar(this);
m_other = new Fie("/dev/blah", this);
...
The key is in that this
parameter, meaning the subobjects are correctly parented to the Foo instance. Hence, when you do
Foo *foo = new Foo;
foo->moveToThread(thread);
the whole object tree rooted in "foo" will be moved into the new thread (moveToThread moves an object and all its children).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With