moveToThread and ownership (destruction)? transfer vs move back vs deleteLater?
-
Hello,
I've just notice a potential crash during my debugging phase, stopping the app at random places to not wait too long and close it "properly" as soon as I get my information I'm testing.QObject: Cannot create children for a parent that is in a different thread. (Parent is QTcpSocket(0x7fd454005a30), parent's thread is QThread(0x5645114a3eb8), current thread is QThread(0x564511495980) QObject: Cannot create children for a parent that is in a different thread. (Parent is QTcpSocket(0x7fd454005a30), parent's thread is QThread(0x5645114a3eb8), current thread is QThread(0x564511495980) QObject::killTimer: Timers cannot be stopped from another thread QObject::~QObject: Timers cannot be stopped from another thread Destruction NntpConnection "Poster #1 {NntpCon #2}" QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread QObject::killTimer: Timers cannot be stopped from another thread QObject::~QObject: Timers cannot be stopped from another thread Destruction NntpConnection "Poster #2 {NntpCon #3}" QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread QObject::killTimer: Timers cannot be stopped from another thread QObject::~QObject: Timers cannot be stopped from another thread Destruction Poster # 0
Basically Qt seems to not like when we destruct an active object from another thread from where it has been moved....
So in general, what you guys do?- moving them back to the owner thread to be destroyed
- let them independent and destroy themselves using deleteLater
- change the ownership to an object living in the same thread where it lives
I guess the easiest and standard Qt way is to use deleteLater?
I'm still used to have owner for my objects that are in charge to free the memory they allocated but that's not automatically the way nowadays especially with Qt active objects (meaning QObjects that live their life asynchronously)Question. If I do that? How can I make sure they've finished the task they could have to do on deletion (logging / releasing resources...). Make sure they will be deleted...
Is this process safe: sending them a signal to warn the application is closing so they can disconnect all their connections to not having new scheduled except a deleteLater.
Well it still doesn't seem so clean to me.
Maybe it's better when they receive such signal to make them move back to the main thread where they will be destroyed? -
well following the QThread doc:
void QThread::finished()
This signal is emitted from the associated thread right before it finishes executing.
When this signal is emitted, the event loop has already stopped running. No more events will be processed in the thread, except for deferred deletion events. This signal can be connected to QObject::deleteLater(), to free objects in that thread.
So at the end, I'm just doing a
quit
on my threads. I've connected all the object I've moved there like proposed above. So all my QObject allocated in the main thread but moved in another one are no more destructed by the object that created them.
Works like a charm :) -
M mbruel has marked this topic as solved on