Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. main and background thread example
Forum Updated to NodeBB v4.3 + New Features

main and background thread example

Scheduled Pinned Locked Moved Unsolved General and Desktop
20 Posts 3 Posters 8.1k Views 2 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.
  • SGaistS Offline
    SGaistS Offline
    SGaist
    Lifetime Qt Champion
    wrote on last edited by
    #4

    Well, if you thread just started to sleep, you'll have to wait for your 5 seconds before it ends properly.

    Do you really have that kind of loop in your application ? It could be reworked to use e.g. a QTimer in a worker object.

    Interested in AI ? www.idiap.ch
    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

    1 Reply Last reply
    0
    • U Offline
      U Offline
      user4592357
      wrote on last edited by
      #5

      i'll try using QTimer instead of this_thread::sleep_for(). but it still blows my mind how my previous implementation worked the way i wanted with this code.

      and is everything else okay with this code (i.e. the use of atomic bool etc.)?

      1 Reply Last reply
      0
      • U Offline
        U Offline
        user4592357
        wrote on last edited by
        #6

        i can't figure out how to do that. this is what i have right now:

        #include <QtWidgets/QMainWindow>
        #include <QApplication>
        #include <QObject>
        #include <QThread>
        #include <iostream>
        #include <thread>
        #include <QtWidgets/QLabel>
        #include <atomic>
        #include <QTimer>
        
        std::atomic<bool> bMainThreadRunning { true };
        
        class ThreadObj : public QObject {
        public:
        	ThreadObj() : counter(0) {}
        	void work() {
        		auto timer = new QTimer;
        		//timer.setInterval(3000);
        		connect(timer, &QTimer::timeout, this, &ThreadObj::inc);
        		timer->start(3000);
        	}
        	void inc() { 
        		while(bMainThreadRunning)
        			++counter;
        	}
        private:
        	int counter { 0 };
        };
        
        class Obj {
        public:
        	void start() {
        		ThreadObj obj;
        		m_thread = std::thread(&ThreadObj::work, &obj);
        	}
        	void onMainThreadFinished() {
        		bMainThreadRunning = false;
        		m_thread.join();
        	}
        private:
        	std::thread m_thread;
        };
        
        int main(int argc, char *argv[]) {
        	QApplication a(argc, argv);
        	Obj o;
        	o.start();
        
        	QWidget w;
        	w.show();
        
        	auto ret = a.exec();
        	o.onMainThreadFinished();
        
        	return 0;
        }
        
        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #7

          You forgot you used a std::thread. Why not use QThread since you are using Qt and a worker object ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          1
          • U Offline
            U Offline
            user4592357
            wrote on last edited by user4592357
            #8

            i did that. what i need is, when in background thread something weird happens, i tell the main thread to show a message box. then if at some time the "good" state of background thread is restored, main thread closes the message box.

            here's what i have now. actually the application works. but at some points it crashes. looking at the crash log i can say that the reason is the background thread but i don't see how my implementation is wrong. i appended the crash log after code.

            class BgThread : public QThread {
            	Q_OBJECT
            public:
            	explicit BgThread (const int &nSeconds, QObject *parent = nullptr) : QThread(parent), interval(1000 * nSeconds) /* to milliseconds */  {}
            
            	void onStopBgThread() { running = false; }
            
            signals:
            	void somethingWentWrong();
                    void restoreGoodState();
            
            private slots:
            	void performWork() {
                         if(/* something went wrong */) {
            		emit somethingWentWrong();
            		good_state = false;
            	     } else if(!good_state) { // means going from bad state to good state
            		emit restoreGoodState();
            		good_state = true;
            	     }
                    }
            
            private:
            	void run() override {
                        QTimer timer;
            	    connect(&timer, SIGNAL(timeout()), this, SLOT(performWork()), Qt::DirectConnection);
            	    timer.start(interval);
            
                        exec();
                        quit();
                        wait();
                    }
            
            private:
            	int interval;
                    bool running { true };
                    bool good_state { true };
            };
            
            class MainApp {
            public:
                void start_bg_thread(const int seconds) {
                   	thread = new BgThread { seconds, this };
                    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
            	connect(thread, SIGNAL(somethingWentWrong()), SLOT(onSomethingWentWrong()));
                    connect(thread, SIGNAL(restoreGoodState()), SLOT(onRestoreGoodState()));
            	thread->start();
                }
            
                void stop_bg_thread() {
            	thread->onStopBgThread();
                }
            
            public slots:
                void onSomethingWentWrong() {
            	if(!msgBox) {
            		msgBox= new QMessageBox(window());
            		msgBox->setIcon(QMessageBox::Warning);
            		msgBox->setWindowTitle("window title");
            		msgBox->setText("message box text");
            		const auto pExitBtn = msgBox->addButton(tr("Exit"), QMessageBox::AcceptRole);
            		connect(pExitBtn, SIGNAL(clicked()), qApp, SLOT(quit()));
            	}
            	msgBox->exec();	
                }
            
                void onRestoreGoodState() {
            	msgBox->close();
                }
            private:
                BgThread *thread { nullptr };
                QMessageBox *msgBox;
            };
            

            this is basically it. and somewhere in the app init process i call

            MainApp app;
            app.start_bg_thread(5);
            

            the crash log is something like this (stacktrace):

            do_system () from /lib64/libc.so.6
            system () from /lib64/libc.so.6
            // call signal handler
            ...
            pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
            QThread::msleep(unsigned long) ()
            start_thread () from /lib64/libpthread.so.0
            clone () from /lib64/libc.so.6
            waitpid () from /lib64/libc.so.6
            do_system () from /lib64/libc.so.6
            system () from /lib64/libc.so.6
            // call signal handler
            BgThread::onStopBgThread ()
            MainApp::qt_metacall(QMetaObject::Call, int, void**) ()
            QMetaObject::activate(QObject*, QMetaObject const*, int, void**) ()
            QCoreApplication::exec()
            main ()
            
            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #9

              Did you check the memory used by you application ?

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              U 1 Reply Last reply
              0
              • SGaistS SGaist

                Did you check the memory used by you application ?

                U Offline
                U Offline
                user4592357
                wrote on last edited by user4592357
                #10

                @SGaist

                what do you mean by check? and no, how should i?

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #11

                  Using the top command for example. Valgrind etc.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  U 1 Reply Last reply
                  1
                  • SGaistS SGaist

                    Using the top command for example. Valgrind etc.

                    U Offline
                    U Offline
                    user4592357
                    wrote on last edited by
                    #12

                    @SGaist

                    okay, thanks.
                    one last question, as you can see, on timer's timeout i execute a function. is it possible stop the timer (so the function won't be executed), and then restart it again?

                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #13

                      Yes:
                      QTimer::stop
                      QTimer::start

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      U 1 Reply Last reply
                      3
                      • SGaistS SGaist

                        Yes:
                        QTimer::stop
                        QTimer::start

                        U Offline
                        U Offline
                        user4592357
                        wrote on last edited by
                        #14

                        @SGaist

                        hi again,
                        i ran valgrind and it says there's a memory leak on exec() which is in run() overridden method. so what's wrong?

                        1 Reply Last reply
                        0
                        • U user4592357

                          i wanna write a basic thread example. here's the idea:
                          i have the main event loop. before calling app.exec(), i create an object which itself creates an object and puts it in a separate thread for running. i need some way to tell the background thread that main thread has finished (to join()), so i have a bool to indicate that.

                          however, when the application exits, something goes wrong. i'm running it using visual studio and the debugging session won't stop. i don't understand what's wrong. here's the code:

                          #include <QApplication>
                          #include <QObject>
                          #include <QThread>
                          #include <iostream>
                          #include <thread>
                          #include <QtWidgets/QLabel>
                          #include <atomic>
                          
                          std::atomic<bool> bMainThreadRunning { true };
                          
                          class ThreadObj {
                          public:
                          	void work() {
                          		while(bMainThreadRunning) {
                          			++counter;
                          			std::this_thread::sleep_for(std::chrono::seconds(5));
                          		}
                          	}
                          private:
                          	int counter { 0 };
                          };
                          
                          class Obj {
                          public:
                          	void start() {
                          		ThreadObj obj;
                          		m_thread = std::thread(&ThreadObj::work, &obj);
                          	}
                          	void onMainThreadFinished() {
                          		bMainThreadRunning = true;
                          		m_thread.join();
                          	}
                          private:
                          	std::thread m_thread;
                          };
                          
                          int main(int argc, char *argv[])
                          {
                          	QApplication a(argc, argv);
                          	Obj o;
                          	o.start();
                          
                          	QWidget w;
                          	w.show();
                          
                          	auto ret = a.exec();
                          	o.onMainThreadFinished();
                          
                          	return 0;
                          }
                          
                          VRoninV Offline
                          VRoninV Offline
                          VRonin
                          wrote on last edited by
                          #15

                          @user4592357 said in main and background thread example:

                          ThreadObj obj;
                          m_thread = std::thread(&ThreadObj::work, &obj);

                          obj is allocated on the stack, it will go out of scope and delete itself

                          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                          ~Napoleon Bonaparte

                          On a crusade to banish setIndexWidget() from the holy land of Qt

                          U 1 Reply Last reply
                          3
                          • VRoninV VRonin

                            @user4592357 said in main and background thread example:

                            ThreadObj obj;
                            m_thread = std::thread(&ThreadObj::work, &obj);

                            obj is allocated on the stack, it will go out of scope and delete itself

                            U Offline
                            U Offline
                            user4592357
                            wrote on last edited by
                            #16

                            @VRonin

                            hi, thanks for the reply.
                            the code has been modified since the first post (see my last code-post), so it's not the problem

                            1 Reply Last reply
                            0
                            • VRoninV Offline
                              VRoninV Offline
                              VRonin
                              wrote on last edited by
                              #17

                              https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

                              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                              ~Napoleon Bonaparte

                              On a crusade to banish setIndexWidget() from the holy land of Qt

                              U 1 Reply Last reply
                              0
                              • VRoninV VRonin

                                https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

                                U Offline
                                U Offline
                                user4592357
                                wrote on last edited by
                                #18

                                @VRonin

                                i've read similar articles, saying "you shouldn't subclass QThread". in my case i need to do that.

                                1 Reply Last reply
                                0
                                • SGaistS Offline
                                  SGaistS Offline
                                  SGaist
                                  Lifetime Qt Champion
                                  wrote on last edited by SGaist
                                  #19

                                  Out of curiosity, what are you doing that requires to subclass QThread ?

                                  Interested in AI ? www.idiap.ch
                                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                  U 1 Reply Last reply
                                  0
                                  • SGaistS SGaist

                                    Out of curiosity, what are you doing that requires to subclass QThread ?

                                    U Offline
                                    U Offline
                                    user4592357
                                    wrote on last edited by
                                    #20

                                    @SGaist

                                    nothing requires it. it's just that the whole implementation is done and i don't wanna change everything

                                    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