Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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
    }

  • Lifetime Qt Champion

    @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 use DirectConnection 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.


Log in to reply