2016-02-25 19:23 GMT+01:00 Elvis Stansvik <elvst...@gmail.com>: > 2016-02-25 19:10 GMT+01:00 Elvis Stansvik <elvst...@gmail.com>: >> 2016-02-25 18:24 GMT+01:00 Murphy, Sean <smur...@walbro.com>: >>>> > Foo() : QObject(nullptr) { >>>> > moveToThread(&m_thread); >>>> > m_thread.start(); >>>> > } >>>> > >>>> > ~Foo() { >>>> > m_thread.quit(); >>>> > m_thread.wait(); >>>> > } >>>> >>>> This destructor is either never run or deadlocks. >>>> >>>> A QObject can only be destroyed in its thread of affinity. So the above is >>>> running in that m_thread thread, which means it hasn't exited. Waiting for >>>> it >>>> to exit will wait forever. >>> >>> Just when I think I have QObjects and QThreads figured out, I realize I >>> don't... How do I correctly handle my situation? >>> >>> I've got a QObject-based class that talks to a custom device and needs to >>> block while making reads/writes to that device. This thread runs the entire >>> duration of my application, because the work it's doing never finishes, it >>> just monitors the device for messages and notifies my UI class when data >>> comes in. >>> >>> So currently I'm doing this: >>> >>> myGUIObject.h: >>> private: >>> myBlockingObject* blocking; >>> QThread* thread; >>> >>> myGUIObject.cpp: >>> myGUIObject() >>> { >>> thread = new QThread(this); >>> blocking = new myBlockingObject(); >>> blocking->moveToThread(thread); >>> } >>> >>> How/where do I properly delete "blocking"? Right now I'm doing this: >>> ~myGUIObject() >>> { >>> thread->exit(); >>> blocking->deleteLater(); >>> } >>> >>> But Thiago's comment "A QObject can only be destroyed in its thread of >>> affinity" sounds like it's not the right way to do it? >>> Sean >> >> I was in a similar situation some years ago, talking to a USB/serial >> device in a separate thread. I had a look at the code, and what I did >> back then was to connect the finished signal of the thread to the >> deleteLater() slot of the object I had moved to the thread. I actually >> did the same with the thread itself. So the connect() calls I did to >> ensure cleanup looked something like this: >> >> // Connect to thread signals to start the sensor and clean up. >> connect(m_sensorThread, SIGNAL(started()), sensor, SLOT(start())); >> connect(m_sensorThread, SIGNAL(finished()), sensor, SLOT(deleteLater())); >> connect(m_sensorThread, SIGNAL(finished()), m_sensorThread, >> SLOT(deleteLater())); >> >> Where sensor is the object I had previously moved to m_senseorThread. >> >> Not sure if your approach above with calling deleteLater() explicitly >> and immediately after thread->exit() is right or wrong, or if doing it >> by signal/slot connections like I did is any better. Just thought I >> would chime in :) > > I see now that this technique is actually right there in the QThread > docs, under "Managing Thread", third paragraph [1]: > > "From Qt 4.8 onwards, it is possible to deallocate objects that live > in a thread that has just ended, by connecting the finished() signal > to QObject::deleteLater()." > > So I think this is the approach you should use. > > The initial example in the class docs also shows the "suicide" > approach of destructing the thread itself: > > connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
Err, I meant the second example, and was going to paste: connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater); Elvis > > In the example you gave, I think you're leaking the thread. > > Cheers, > Elvis > > [1] http://doc.qt.io/qt-5/qthread.html#managing-threads > >> >> Elvis >> >>> _______________________________________________ >>> Interest mailing list >>> Interest@qt-project.org >>> http://lists.qt-project.org/mailman/listinfo/interest _______________________________________________ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest