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
Forum Updated to NodeBB v4.3 + New Features

Exit QThread Cleanly

Scheduled Pinned Locked Moved Language Bindings
2 Posts 2 Posters 2.0k 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