Results 1 to 9 of 9

Thread: Threading without the headache

  1. #1
    Join Date
    May 2010
    Posts
    23
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    2

    Default Threading without the headache

    I was intrigued by the post http://labs.qt.nokia.com/2010/06/17/...oing-it-wrong/ and really like that idea of new way of using threads. So I wrote a simple example, which... does not work
    Qt Code:
    1. #ifndef THREADs_TEST_H
    2. #define THREADs_TEST_H
    3.  
    4. #if defined(_WIN32)
    5. #include <windows.h>
    6. #elif defined(__GNUC__)
    7. #include <unistd.h>
    8. #define Sleep(x) sleep((x)/1000)
    9. #endif //_WIN32
    10.  
    11. #include <iostream>
    12. #include <QThread>
    13. #include <QObject>
    14. #include <QDialog>
    15. #include <QDialogButtonBox>
    16. #include <QBoxLayout>
    17. #include <QPushButton>
    18.  
    19. class Cycler : public QObject
    20. {
    21. Q_OBJECT
    22. public:
    23. Cycler() : QObject() {};
    24. virtual ~Cycler(){stop();};
    25. signals:
    26. void done();
    27. public slots:
    28. void cycle() {
    29. arbeit = true;
    30. int i = 0;
    31. while(arbeit) {
    32. Sleep(1000);
    33. std::cout << i++ << " " << std::flush;
    34. };
    35. emit done(); };
    36. void stop(){ arbeit = false;};
    37. private:
    38. volatile bool arbeit;
    39. };
    40.  
    41. class CyclerDialog: public QDialog
    42. {
    43. Q_OBJECT
    44. public:
    45. explicit CyclerDialog(QWidget* parent = 0, Qt::WindowFlags f = 0) : QDialog(parent, f){
    46. QVBoxLayout *main_layout = new QVBoxLayout;
    47. main_layout->addWidget(buttons);
    48. setLayout(main_layout);
    49.  
    50. cycl.moveToThread(&thrd);
    51. connect(buttons, SIGNAL(accepted()), &thrd, SLOT(start()));
    52. connect(&thrd, SIGNAL(started()), &cycl, SLOT(cycle()));
    53. connect(buttons, SIGNAL(rejected()), &cycl, SLOT(stop()));
    54. connect(&cycl, SIGNAL(done()), &thrd, SLOT(quit())); };
    55.  
    56. virtual ~CyclerDialog(){thrd.wait(1000);};
    57. private:
    58. Cycler cycl;
    59. QThread thrd;
    60. };
    61.  
    62. #endif // THREADs_TEST_H
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #include <QApplication>
    2. #include "threads_test.h"
    3.  
    4. int main(int argc, char *argv[])
    5. {
    6. QApplication app(argc, argv);
    7. CyclerDialog window;
    8. window.show();
    9. return(app.exec());
    10. }
    To copy to clipboard, switch view to plain text mode 

    It is supposed to start printing numbers in std::cout when OK is clicked, and stop when CANCEL is clicked, but apparently stop() slot is never called. WHY????

  2. #2
    Join Date
    Jan 2006
    Location
    Napoli, Italy
    Posts
    621
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    5
    Thanked 86 Times in 81 Posts

    Default Re: Threading without the headache

    Simple.

    Your slot cycle never returns, so the stop slot never be called by eventLoop
    A camel can go 14 days without drink,
    I can't!!!

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

    Onanymous (19th July 2011)

  4. #3
    Join Date
    May 2010
    Posts
    23
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    2

    Default Re: Threading without the headache

    Indeed. How do I fix that?

  5. #4
    Join Date
    Jan 2006
    Location
    Napoli, Italy
    Posts
    621
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    5
    Thanked 86 Times in 81 Posts

    Default Re: Threading without the headache

    Use a QTimer and connect a slot to QTimer::timeout signal.

    When the thread emits the started signal, call QTimer::start and when you want to stop it, call QTime::stop
    A camel can go 14 days without drink,
    I can't!!!

  6. #5
    Join Date
    May 2010
    Posts
    23
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    2

    Default Re: Threading without the headache

    I came up to another solution, basically to move stop() to CyclerDialog, and initiate Cycler with reference to CyclerDialog::arbeit flag. It seems to work.
    Qt Code:
    1. class Cycler : public QObject
    2. {
    3. Q_OBJECT
    4. public:
    5. Cycler(volatile bool &stop_flag) : QObject(), arbeit(stop_flag) {};
    6. virtual ~Cycler(){};
    7. signals:
    8. void done();
    9. public slots:
    10. void cycle() {
    11. arbeit = true;
    12. int i = 0;
    13. while(arbeit) {
    14. Sleep(1000);
    15. std::cout << i++ << " " << std::flush;
    16. };
    17. emit done(); };
    18. private:
    19. volatile bool& arbeit;
    20. };
    21.  
    22. class CyclerDialog: public QDialog
    23. {
    24. Q_OBJECT
    25. public:
    26. explicit CyclerDialog(QWidget* parent = 0, Qt::WindowFlags f = 0) : QDialog(parent, f), cycl(arbeit){
    27. QVBoxLayout *main_layout = new QVBoxLayout;
    28. main_layout->addWidget(buttons);
    29. setLayout(main_layout);
    30.  
    31. cycl.moveToThread(&thrd);
    32. connect(buttons, SIGNAL(accepted()), &thrd, SLOT(start()));
    33. connect(&thrd, SIGNAL(started()), &cycl, SLOT(cycle()));
    34. connect(buttons, SIGNAL(rejected()), this, SLOT(stop()));
    35. connect(&cycl, SIGNAL(done()), &thrd, SLOT(quit())); };
    36.  
    37. virtual ~CyclerDialog(){stop(); thrd.wait(1000);};
    38. public slots:
    39. void stop(){arbeit = false;};
    40. private:
    41. volatile bool arbeit;
    42. Cycler cycl;
    43. QThread thrd;
    44. };
    To copy to clipboard, switch view to plain text mode 

  7. #6
    Join Date
    Jan 2006
    Location
    Napoli, Italy
    Posts
    621
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    5
    Thanked 86 Times in 81 Posts

    Default Re: Threading without the headache

    In general, Synchronizing threads through a shared variable is not a good idea; you should, at least, protect the access with a mutex.

    The problem of your solution is that the eventLoop of the thread cannot elaborate other events because it's blocked by your slot
    A camel can go 14 days without drink,
    I can't!!!

  8. #7
    Join Date
    May 2010
    Posts
    23
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    2

    Default Re: Threading without the headache

    In general you are right, I do not need a thread for the type of problem I made an example for, QTimer would be sufficient in fact.
    But I am rather intertested in a situation when the thread is created just to run some heavy work, and I only need a tool to stop it, the flag then is not really shared, Cycler needs only read access to it, so no mutexes required. To ensure that I could probably make a const function in CyclerDialog returning bool, and initiate the Cycler with a const pointer to CyclerDialog.

  9. #8
    Join Date
    Jan 2006
    Location
    Napoli, Italy
    Posts
    621
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    5
    Thanked 86 Times in 81 Posts

    Default Re: Threading without the headache

    In the cases you descrided you can (and should) use QThreadPool/QRunnable or QtConcurrent.

    For an overview read here
    A camel can go 14 days without drink,
    I can't!!!

  10. #9
    Join Date
    Nov 2010
    Posts
    315
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo
    Thanked 53 Times in 51 Posts

    Default Re: Threading without the headache

    Don't use sleep use timer as mcosta suggested (in you case this is best solution).
    Another solution is to call event loop inside your loop:
    Qt Code:
    1. QApplication::processEvents();
    To copy to clipboard, switch view to plain text mode 
    And last a bit strange solution is replace loop with queued meta calls.
    Qt Code:
    1. void cycle() {
    2. if (arbeit) {
    3. Sleep(1000);
    4. std::cout << i++ << " " << std::flush;
    5. metaObject->invokeMethod(this, "cycle", Qt::QueuedConnection);
    6. } else {
    7. emit done();
    8. }
    9. }
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. Qt::WA_TranslucentBackground and videos headache.
    By Smokex in forum Qt Programming
    Replies: 0
    Last Post: 17th March 2010, 18:40
  2. Dependencies maintenance headache
    By nateriver in forum Qt Tools
    Replies: 3
    Last Post: 27th December 2009, 12:26
  3. Threading...?
    By sekatsim in forum Qt Programming
    Replies: 12
    Last Post: 10th June 2008, 01:14
  4. Qt Threading
    By avh in forum Newbie
    Replies: 7
    Last Post: 30th May 2008, 20:20
  5. Sub-Threading
    By TheGrimace in forum Qt Programming
    Replies: 4
    Last Post: 7th June 2007, 16:38

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
  •  
Qt is a trademark of The Qt Company.