How to delete QThread?
-
Hi, this is a question about running qthread. What I want to do is that when a button is clicked, the two dialogs that are running on two different threads will be closed and threads will be safely deleted. However, every time when I press the button, the dialogs are closed but the program always produces an error saying
QThread: Destroyed while thread is still running 12:40:45: The program has unexpectedly finished.
Below is my code:// This is in the constructor to ensure that sthread (a child class of QObject) is deleted when thread (a subclass of QThread) is finished connect(&thread, &QThread::finished, sthread, &SenderThread::deleteLater, Qt::ConnectionType::DirectConnection); void Sender::on_close_button_clicked() { sthread -> serialisation(3); // Sending signals to another thread thread.quit(); // Quit the thread that this dialog is currently running on close(); // close the current dialog }
//The same purpose as in sender dialog connect(&thread, &QThread::finished, rthread, &ReceiverThread::deleteLater, Qt::ConnectionType::DirectConnection); void Receiver::toClose() { thread.quit();//quit the thread that rthread is running on close();//close the dialog }
-
@Christina123 said in How to delete QThread?:
the two dialogs that are running on two different threads
Why do you want to run two dialogs in different threads? What's the point? This is not supported - all UI related stuff has to run in main thread.
-
Sorry, I wasn't clear about question. What I am doing is that the two dialogs are running on main threads, but some heavy operations such as serialising and deserialising data are moved to threads. Generally speaking, I have one thread that is responsible for serialising data from Sender dialog and the other thread responsible for deserialising data and send it to Receiver dialog. So, in short, it is not dialogs that are moved to threads, but are two QObjects that are move to its own thread. Hope that this is a little bit clear now.
-
@Christina123 said in How to delete QThread?:
but are two QObjects that are move to its own thread
In general, I do it like this:
- add a signal finished() to the worker class, which is emitted, when all is done
- use this signal to cleanup
Example:
auto thread = new QThread(); obj->moveToThread(thread); // stop thread when done connect(obj, &MyObject::finished, thread, &QThread::quit); // delete worker object when done connect(obj, &MyObject::finished, obj, &QObject::deleteLater); // delete worker thread when stopped connect(thread, &QThread::finished, thread, &QThread::deleteLater); // ==> supposing `doWork` is the slot to be called at thread begin connect(thread, &QThread::started, obj, &MyObject::doWork); // start thread thread->start();
-
@Christina123 said in How to delete QThread?:
connect(&thread
Looks like
thread
is allocated on the stack so it might be going out of scope before it finishes.Qt::ConnectionType::DirectConnection
Are you sure about what you are doing here? The
QThread
object belongs to the spawning thread while the worker belongs to the sub-thread. they should not useDirectConnection
generally, just remove this argument and let Qt manage the connection type -
Thank you so much to everyone who replies to me. I think the major problem is what @VRonin said, I declare the thread on the stack instead of heap. As soon as I create the thread on the heap instead of stack, the programs does not unexpectedly finished anymore. This is my modified code:
QThread *thread = new QThread;// thread is created on heap to prevent it goes out of scope connect(thread, &QThread::finished, thread, &QThread::deleteLater); connect(thread, &QThread::finished, rthread, &QThread::deleteLater); thread -> quit(); //quit the thread
-
In a general comp-sci sense it is considered bad form to "kill" a thread. The correct way is to send a notification to the thread that causes it to exit whatever processing loop is running therein. That notification can be a signal, semaphore, or simple sentinel value.