Question About Quitting Application While Worker Thread Working



  • Hi I have a quick question about quitting an application while a worker thread is working.

    The program can be quit either by closing the QMainWindow or clicking quit in the notification area icon menu. The notification area quit menu item calls quit(). When the program quits the backend object (named Replicator) falls out of scope and the destructor is called. Upon quitting the destructor waits for the thread to finish.

    The stopwork signal calls cancelBackup() which stops the worker thread by setting a boolean value to true. The worker object then finishes its processing after reading the boolean. After all processing is done it emits a signal to let the backend object know it is done. The backend object then can tell the worker object to do more processing if there is more work to be done in a work queue. My worker thread code is contained in a worker thread QObject using movetothread().

    If a user quits the application while the worker thread is working and upon the thread worker object finishing its work it emits a signal to the backend object (named Replicator) does the receiving slot for the signal get processed before the application quits? Or does the signal get ignored since the program is trying to quit? If there is more work in the work queue and the receiving slot gets processed then instead of quitting the program would wait until it finishes all work in the work queue (I want the program to quit right away instead). Here's the code (let me know if I need to include more code):

    void ReplicatorMainScreen::quit()
    {
        trayIcon->hide();
        emit stopWork();
        QApplication::quit();
    }
    
    void ReplicatorMainScreen::closeEvent(QCloseEvent *event)
    {
        if (!settings.value("closeToTray",false).toBool())
        {
            emit stopWork();
            event->accept();
        }
    }
    
    Replicator::~Replicator()
    {
        //if (mainScreen)
        if (!firstRun)
            writeSettings();
        workerThread->quit();
        workerThread->wait();
    }
    
    void Replicator::cancelBackup()
    {
        if (isBusy)
            worker->stop();
    }
    
    class Worker : public QObject
    {
        void stop() { cancel = true; }
    }
    
    int main(int argc, char *argv[])
    {
        QtSingleApplication repSAPass("reppass", argc, argv);
        repSAPass.isRunning();
    
        Replicator replicator;
    
        return repSAPass.exec();
    }
    

  • Lifetime Qt Champion

    Hi,

    Your boolean flag might have been "optimized". You should try with a QAtomicInt to manage your loop.



  • I used :
    volatile std::atomic_bool cancel;
    Will the receiving slot get processed though before the program quits?


  • Lifetime Qt Champion

    AFAIR, it should, however when threading with infinite loop is involved, I usually ensure that the stoping is called directly e.g. from the managing class destructor.



  • Thanks SGaist. I opted to just set a boolean upon quitting and check for it in the receiving slot, if it's set then quit otherwise process the events.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.