Results 1 to 5 of 5

Thread: How to make a QThread run continuously?

  1. #1
    Join Date
    Aug 2009
    Location
    United States
    Posts
    45
    Thanks
    20
    Qt products
    Qt4
    Platforms
    Windows

    Default How to make a QThread run continuously?

    I need to have a thread running separate from the main application thread; it's going to watch a serial port and emit a signal when new data arrives, and the main window picks up the signal and stores the new data. How can I make a thread that keeps running forever? Here's my relevant code:

    Qt Code:
    1. // in the main window's file
    2. Thread *myThread = new Thread();
    3. connect(myThread, SIGNAL(testSignal(QString)), this, SLOT(testSlot(QString)));
    4.  
    5.  
    6. // in the .h file
    7. class Thread : public QThread
    8. {
    9. Q_OBJECT
    10.  
    11. public:
    12. Thread();
    13. signals:
    14. void testSignal(QString message);
    15. protected:
    16. void run();
    17. private:
    18. };
    19.  
    20. // in the .cpp file
    21. void Thread::run()
    22. {
    23. while(1)
    24. {
    25. emit(testSignal("hello world!"));
    26. }
    27. }
    28.  
    29. Thread::Thread()
    30. {
    31. run();
    32. }
    To copy to clipboard, switch view to plain text mode 

    When I try to run the application, my CPU usage goes up to about 100% - I assume because the thread is running without any sort of "wait" programmed in. So I tried adding the "sleep(seconds)" function inside the while loop, but for some reason this stalls the whole application, not just the thread.

    Any idea what I should do?

    Thanks!

  2. #2
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How to make a QThread run continuously?

    First : don't call run() in constructor.
    Second : read once more detailed description of QThread.

    With this construction of Thread::run You are blocking event loop.

  3. The following user says thank you to Lesiok for this useful post:

    N3wb (17th April 2010)

  4. #3
    Join Date
    Aug 2009
    Location
    United States
    Posts
    45
    Thanks
    20
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to make a QThread run continuously?

    Thanks for linking to the documentation! I had been reading the 3.3 documentation by accident, which wasn't nearly as informative..

    So, if I understand correctly, the event loop is supposed to be inside of "exec()," correct? Would this be a legitimate way of implementing what I want to do?

    Qt Code:
    1. // inside main window file
    2. Thread *myThread = new Thread();
    3. connect(myThread, SIGNAL(testSignal(QString)), this, SLOT(testSlot(QString)));
    4. myThread->start();
    5.  
    6.  
    7.  
    8. // inside thread's .h file
    9. class Thread : public QThread
    10. {
    11. Q_OBJECT
    12.  
    13. public:
    14. Thread();
    15. signals:
    16. void testSignal(QString message);
    17. protected:
    18. void run();
    19. int exec();
    20. private:
    21. };
    22.  
    23.  
    24.  
    25. // inside thread's .cpp file
    26. void Thread::run()
    27. {
    28. exec();
    29. }
    30.  
    31. Thread::Thread()
    32. {
    33. }
    34.  
    35. int Thread::exec()
    36. {
    37. while(1)
    38. {
    39. emit(testSignal("hello world!"));
    40. sleep(1);
    41. }
    42. }
    To copy to clipboard, switch view to plain text mode 


    Why is there difference between having the loop in the "run()" or "exec()" functions, though? It's the same code in both functions, but for some reason only works in the "exec()" function?

    Thanks!

  5. #4
    Join Date
    Dec 2008
    Location
    Poland
    Posts
    383
    Thanks
    52
    Thanked 42 Times in 42 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: How to make a QThread run continuously?

    Here is how thread work's (AFAIK, please correct me if I'm wrong), using Your example:
    Qt Code:
    1. Thread *myThread = new Thread();
    To copy to clipboard, switch view to plain text mode 
    call a constructor:
    Qt Code:
    1. Thread::Thread()
    2. {
    3. }
    To copy to clipboard, switch view to plain text mode 
    Then thread is on the stack, so you can fire it up like so:
    Qt Code:
    1. myThread->start();
    To copy to clipboard, switch view to plain text mode 
    and in the thread this protected run() is always called, as manual said "starting point for the thread":
    Qt Code:
    1. void Thread::run()
    2. {
    3. exec();
    4. }
    To copy to clipboard, switch view to plain text mode 
    Here You want to start exec()ution of the thread. Calling exec() tell thread to enter event loop. Thread run until exit()/quit() is called, so In Your case forever. Exec() is int because it is similar to main function "int main()" in normal program, it returns int at the end of execution to let you know if there was error int != 0.
    Qt Code:
    1. int Thread::exec()
    2. {
    3. while(1)
    4. {
    5. emit(testSignal("hello world!"));
    6. sleep(1);
    7. }
    8. }
    To copy to clipboard, switch view to plain text mode 
    Your thread runs forever, because no exit() or quit() is called, and the signal is emitted each 1s.
    So to sum it up, run() is called after mythread->start(), and exec() enters event loop for the thread.
    You could do something like this also:
    Qt Code:
    1. void Thread::run()
    2. {
    3. myfirstfunction();
    4. mysecoundfunction();
    5. exec();
    6. }
    7. void Thread:: myfirstfunction()
    8. {
    9. //do some heavy duty stuff / blocking gui operation
    10. }
    11. void Thread:: mysecoundfunction()
    12. {
    13. //proces data
    14. exit();
    15. }
    To copy to clipboard, switch view to plain text mode 
    And, depending on what is in myfirs/secound function, the execution flow is first then secound and end of the thread. Also note that if You don't call exit() / quit() inside thread, thread runs "forever" (actually main app don't know if thread execution ended or not ), and using delete mythread() yields error "QThread: Destroyed while thread is still running" or similar. Depending what you are doing in the thread, or on what point You call delete application crash or simply runs but only output error. Also always delete after new because this is mem leek, and depending on Your implementation or data inside thread you can run out of the memory.
    I hope this helps to understand how thread works, and again this information is as I see the thread, maybe there is some mistake so please point them out.
    Best regards.
    Last edited by Talei; 18th April 2010 at 00:51.

  6. The following user says thank you to Talei for this useful post:

    N3wb (20th April 2010)

  7. #5
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How to make a QThread run continuously?

    Quote Originally Posted by N3wb View Post
    Why is there difference between having the loop in the "run()" or "exec()" functions, though? It's the same code in both functions, but for some reason only works in the "exec()" function?

    Thanks!
    There is nothing difference. Here is code of original QThread::exec method :
    Qt Code:
    1. int QThread::exec()
    2. {
    3. Q_D(QThread);
    4. QMutexLocker locker(&d->mutex);
    5. d->data->quitNow = false;
    6. QEventLoop eventLoop;
    7. locker.unlock();
    8. int returnCode = eventLoop.exec();
    9. return returnCode;
    10. }
    To copy to clipboard, switch view to plain text mode 
    As You see You never create and exec event loop. Yours Thread class must be defined something like that :
    Qt Code:
    1. class Thread : public QThread
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. Thread();
    7. signals:
    8. void testSignal(QString message);
    9. slots:
    10. void mTimeOut();
    11. protected:
    12. void run();
    13. };
    14.  
    15. Thread::Thread()
    16. {
    17. }
    18.  
    19. void Thread::run()
    20. {
    21. QTimer::singleShot(0, this, SLOT(mTimeOut()));
    22.  
    23. exec();
    24. }
    25.  
    26. void Thread::mTimeOut()
    27. {
    28. //do what You need in one step
    29. emit(testSignal("hello world!"));
    30. //do sleep and after start next step
    31. QTimer::singleShot(1, this, SLOT(mTimeOut()));
    32. }
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. Replies: 6
    Last Post: 10th March 2011, 16:42
  2. Replies: 4
    Last Post: 26th June 2008, 18:41
  3. Window OS make distclean && qmake && make one line
    By patrik08 in forum General Programming
    Replies: 4
    Last Post: 22nd March 2007, 10:43
  4. Replies: 6
    Last Post: 17th March 2006, 17:48
  5. Replies: 1
    Last Post: 20th January 2006, 12:01

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.