Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Language Bindings
  4. Exit QThread Cleanly
Qt 6.11 is out! See what's new in the release blog

Exit QThread Cleanly

Scheduled Pinned Locked Moved Language Bindings
2 Posts 2 Posters 2.3k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    Gwal Ashish
    wrote on last edited by
    #1

    I am currently developing a GUI front-end application for DVR. After completing the coding part of it, I have tested it many times and it is working fine.

    I am using QThread in my code for checking the state of the backend server 24X7. I do not have any proper solution for closing second thread cleanly when my main thread i.e. GUI thread quits.

    Here is the code which I have been using right now for second thread.

    @void thread::run()
    {

    forever
    {
    forever
    {
    checking some condition........
    emit <signal>;
    break;
    }
    forever
    {
    checking some condition........
    emit <signal>;
    break;
    }
    }
    }@

    Please suggest any solution for the above scenario.

    1 Reply Last reply
    0
    • jazzycamelJ Offline
      jazzycamelJ Offline
      jazzycamel
      wrote on last edited by
      #2

      Before I answer your question I will first say that, despite examples given in the docs, it is generally considered a bad idea to subclass QThread and instead create a worker object that is moved into a thread. To stop a QThread you need to call quit() and, if that fails, terminate(). The issue here is that you're running a blocking method and no event loop so these methods will not work on there own. What you therefore need is a flag that is checked on every iteration of the forever loop and set by a signal/slot call from your main thread when the GUI exits. The following files form a minimal working example:

      widget.h
      @
      #ifndef WIDGET_H
      #define WIDGET_H

      #include <QWidget>

      class QThread;

      class Widget : public QWidget
      {
      Q_OBJECT

      public:
      explicit Widget(QWidget *parent = 0);
      ~Widget();

      private:
      QThread *thread;

      signals:
      void stopThread();

      public slots:
      void start();
      void tick();
      };

      #endif // WIDGET_H
      @

      widget.cpp
      @
      #include "widget.h"
      #include "threaded.h"

      #include <QVBoxLayout>
      #include <QPushButton>
      #include <QThread>
      #include <QDebug>

      Widget::Widget(QWidget *parent) :
      QWidget(parent)
      {
      QVBoxLayout *l=new QVBoxLayout(this);

      QPushButton *startButton=new QPushButton("Start", this);
      connect(startButton, SIGNAL(clicked()), this, SLOT(start()));
      l->addWidget(startButton);
      

      }

      Widget::~Widget()
      {
      if(thread->isRunning()){
      emit stopThread();
      thread->quit();
      if(!thread->wait(5000)){
      thread->terminate();
      if(!thread->wait(5000)) qDebug() << "Failed to terminate!";
      }
      }
      }

      void Widget::start(){
      thread=new QThread();
      Threaded *threaded=new Threaded();
      connect(this, SIGNAL(stopThread()), threaded, SLOT(stop()));
      connect(threaded, SIGNAL(tick()), this, SLOT(tick()));
      connect(thread, SIGNAL(started()), threaded, SLOT(work()));
      threaded->moveToThread(thread);
      thread->start();
      }

      void Widget::tick(){
      qDebug() << "tick";
      }
      @

      threaded.h
      @
      #ifndef THREADED_H
      #define THREADED_H

      #include <QObject>

      class Threaded : public QObject
      {
      Q_OBJECT
      public:
      explicit Threaded(QObject *parent = 0);

      private:
      bool mStop;

      signals:
      void tick();

      public slots:
      void work();
      void stop();
      };

      #endif // THREADED_H
      @

      threaded.cpp
      @
      #include "threaded.h"

      #include <QMutex>
      #include <QWaitCondition>
      #include <QCoreApplication>

      Threaded::Threaded(QObject *parent) :
      QObject(parent), mStop(false)
      {}

      void Threaded::work(){
      QMutex dummy;
      QWaitCondition waitCondition;

      forever{
          dummy.lock();
          waitCondition.wait(&dummy, 1000);
          emit tick();
          dummy.unlock();
          QCoreApplication::processEvents();
          if(mStop) break;
      }
      

      }

      void Threaded::stop(){
      mStop=true;
      }
      @

      main.cpp
      @
      #include <QtGui/QApplication>
      #include "widget.h"

      int main(int argc, char *argv[])
      {
      QApplication a(argc, argv);
      Widget w;
      w.show();

      return a.exec&#40;&#41;;
      

      }
      @

      Hope this helps ;o)

      For the avoidance of doubt:

      1. All my code samples (C++ or Python) are tested before posting
      2. As of 23/03/20, my Python code is formatted to PEP-8 standards using black from the PSF (https://github.com/psf/black)
      1 Reply Last reply
      0

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved