Results 1 to 20 of 30

Thread: QThread exec proplem to stop...

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    8
    Thanked 541 Times in 521 Posts

    Default Re: QThread exec proplem to stop...

    Yes, exactly what I said.
    But Patrik's problem is that he cannot stop the thread .
    Everything works well ( he starts the event loop and all ), but the thread doesn't ever finish because he wasn't calling exit or quit anywhere.

    One has to call exec() within run() to start the event loop for the thread so that signals can be emitted.
    Not so sure about that. Signals can be emitted from within the thread to other threads - this works because the are nothing but some events. It is similar to calling QApplication: postEvent( someThread, someEvent ).

    Without it QHttp or any other class that uses events (signals included) won't function properly
    Yes, any event that targets this thread( without an event loop ) is a potential danger to the entire application ( therefore to other threads ).
    It happened to me - I was trying to create a pixmap( load it from disk ) in some thread that didn't have an event loop. But QPixmapCache( used internally by QPixmap ) sends timer events to the creator thread.
    This resulted in the GUI thread's event loop getting compromised ( most of the times stopped processing it's own events ).
    I am not sure if you remember it, but it was about the same time when I had problems with that crash in QProgressDialog.
    Anyway, to make a long story short ( too late, I guess ), signals can be emitted from threads without event handlers but the other way around is not safe at all - actually it won't work( since we're talking about queued connection ).

    Please note that this doesn't concern the finished() signal as it is emitted from the parent (where QThread object was created) thread.
    Good to know that.

    Regards

  2. The following user says thank you to marcel for this useful post:

    patrik08 (20th May 2007)

  3. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,373
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: QThread exec proplem to stop...

    Quote Originally Posted by marcel View Post
    Not so sure about that. Signals can be emitted from within the thread to other threads - this works because the are nothing but some events. It is similar to calling QApplication: postEvent( someThread, someEvent ).
    I'm talking about using signals within a thread, but this generally applies to using slots across threads as well.

    Yes, any event that targets this thread( without an event loop ) is a potential danger to the entire application ( therefore to other threads ).
    If a thread doesn't have an event loop, all its objects' events won't ever be processed.

  4. The following user says thank you to wysota for this useful post:

    patrik08 (20th May 2007)

  5. #3
    Join Date
    May 2006
    Posts
    788
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows
    Thanks
    49
    Thanked 48 Times in 46 Posts

    Default Re: QThread exec proplem to stop...

    Hurra now is run .... and i can take 10 or more remote dir ls -al on 800
    millisecond. (lan)

    the next QHttp i build direct inside QThread to suppress many class...


    Qt Code:
    1. /*
    2.  on subclass QHttp i suppress close on this way ..
    3.  i observer that QThread wait for close ...
    4. ( opinion or mistake? whitout this close nothing run.. )
    5. */
    6. void close()
    7. {
    8. deleteLater();
    9. }
    10.  
    11.  
    12.  
    13. class DavListDir : public QThread
    14. {
    15. Q_OBJECT
    16. public:
    17. void run();
    18. QString GetxmlData();
    19. void SetUrl( QUrl u );
    20. signals:
    21. void statusMessage(QString);
    22. void TimeEnd();
    23. private:
    24. QUrl urltogrep;
    25. QString ned;
    26. HTTP_propfind *jobb;
    27. public slots:
    28. void quit();
    29.  
    30. };
    31. void DavListDir::quit()
    32. {
    33. ned = jobb->GetDAVData();
    34. emit finished();
    35. std::cout << "----- quit call..." << std::endl;
    36. exit(0);
    37. }
    38. void DavListDir::SetUrl( QUrl u )
    39. {
    40. urltogrep = QUrl(u);
    41. jobb = new HTTP_propfind(urltogrep); /* QHttp first setup header .... */
    42. connect(jobb, SIGNAL(done(bool)), this, SLOT(quit()));
    43. }
    44.  
    45. QString DavListDir::GetxmlData()
    46. {
    47. return ned;
    48. }
    49.  
    50. void DavListDir::run()
    51. {
    52. if (!urltogrep.isValid()) {
    53. quit();
    54. return;
    55. }
    56. jobb->start();
    57. exec(); /* QHttp start request */
    58. forever{
    59. if (isFinished()) {
    60. ned = jobb->GetDAVData();
    61. emit finished();
    62. }
    63. };
    64. }
    To copy to clipboard, switch view to plain text mode 

  6. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,373
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: QThread exec proplem to stop...

    Hmmm.... This code is.... well... how should I say that.... hmm... incorrect
    This way the thread will never terminate... What's the point of spinning in the forever loop?

  7. #5
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    8
    Thanked 541 Times in 521 Posts

    Default Re: QThread exec proplem to stop...

    Quote Originally Posted by wysota View Post
    Hmmm.... This code is.... well... how should I say that.... hmm... incorrect
    This way the thread will never terminate... What's the point of spinning in the forever loop?
    It will finish, but only if he calls quit() outside the thread ...This is one crazy thread.

    Oh, BTW QThread::quit() is not virtual, neither is exit. So I'm not sure how correct it is to reimplement it. Anyway, if qt uses your class, it will call the base class version.

    On the other hand, if you use it on an instance of your class, it will get called ok.
    Why not rename it to something else, and call exit or quit in that function, as you do now.

  8. #6
    Join Date
    May 2006
    Posts
    788
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows
    Thanks
    49
    Thanked 48 Times in 46 Posts

    Default Re: QThread exec proplem to stop...

    Quote Originally Posted by marcel View Post
    It will finish, but only if he calls quit() outside the thread ...This is On the other hand, if you use it on an instance of your class, it will get called ok.
    Why not rename it to something else, and call exit or quit in that function, as you do now.
    is running ....

    Qt Code:
    1. class DavListDir : public QThread
    2. {
    3. Q_OBJECT
    4. public:
    5. void run();
    6. void SetUrl( QUrl u );
    7. signals:
    8. void DataXml(QString);
    9. /*void TimeEnd();*/
    10. private:
    11. QUrl urltogrep;
    12. QString ned;
    13. HTTP_propfind *jobb;
    14. public slots:
    15. void grepdata();
    16.  
    17. };
    18. void DavListDir::grepdata()
    19. {
    20. ned = jobb->GetDAVData();
    21. if (ned.size() > 0) {
    22. emit DataXml(ned);
    23. exit(0);
    24. }
    25. }
    26. void DavListDir::SetUrl( QUrl u )
    27. {
    28. urltogrep = QUrl(u);
    29. jobb = new HTTP_propfind(urltogrep); /* QHttp first setup header .... */
    30. connect(jobb, SIGNAL(done(bool)), this, SLOT(grepdata()));
    31. }
    32. void DavListDir::run()
    33. {
    34. if (!urltogrep.isValid()) {
    35. quit();
    36. return;
    37. }
    38. jobb->start(); /* QHttp start request */
    39. exec();
    40. forever{
    41. if (isFinished()) {
    42. emit grepdata();
    43. }
    44. };
    45. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by patrik08; 20th May 2007 at 22:30.

  9. #7
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    8
    Thanked 541 Times in 521 Posts

    Default Re: QThread exec proplem to stop...

    Quote Originally Posted by patrik08 View Post
    is running ....

    Qt Code:
    1. class DavListDir : public QThread
    2. {
    3. Q_OBJECT
    4. public:
    5. void run();
    6. void SetUrl( QUrl u );
    7. signals:
    8. void DataXml(QString);
    9. /*void TimeEnd();*/
    10. private:
    11. QUrl urltogrep;
    12. QString ned;
    13. HTTP_propfind *jobb;
    14. public slots:
    15. void grepdata();
    16.  
    17. };
    18. void DavListDir::grepdata()
    19. {
    20. ned = jobb->GetDAVData();
    21. if (ned.size() > 0) {
    22. emit DataXml(ned);
    23. }
    24. }
    25. void DavListDir::SetUrl( QUrl u )
    26. {
    27. urltogrep = QUrl(u);
    28. jobb = new HTTP_propfind(urltogrep); /* QHttp first setup header .... */
    29. connect(jobb, SIGNAL(done(bool)), this, SLOT(grepdata()));
    30. }
    31. void DavListDir::run()
    32. {
    33. if (!urltogrep.isValid()) {
    34. quit();
    35. return;
    36. }
    37. jobb->start(); /* QHttp start request */
    38. exec();
    39. forever{
    40. if (isFinished()) {
    41. emit grepdata();
    42. }
    43. };
    44. }
    To copy to clipboard, switch view to plain text mode 
    No, not OK.
    isFinished always returns false when called within thread ( especially from run ).

  10. #8
    Join Date
    May 2006
    Posts
    788
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows
    Thanks
    49
    Thanked 48 Times in 46 Posts

    Default Re: QThread exec proplem to stop...

    this run .... && having time out if loop....

    is this better ....?

    Qt Code:
    1. class DavListDir : public QThread
    2. {
    3. Q_OBJECT
    4. public:
    5. void run();
    6. void SetUrl( QUrl u );
    7. signals:
    8. void DataXml(QString);
    9. void TimeEnd();
    10. private:
    11. QUrl urltogrep;
    12. QString ned;
    13. HTTP_propfind *jobb;
    14. bool waiting;
    15. int decimalsec;
    16. public slots:
    17. void grepdata();
    18.  
    19. };
    20. void DavListDir::grepdata()
    21. {
    22. ned = jobb->GetDAVData();
    23. if (ned.size() > 0) {
    24. emit DataXml(ned);
    25. waiting = false;
    26. quit();
    27. }
    28. }
    29. void DavListDir::SetUrl( QUrl u )
    30. {
    31. decimalsec = 0;
    32. waiting = true;
    33. urltogrep = QUrl(u);
    34. jobb = new HTTP_propfind(urltogrep); /* QHttp first setup header .... */
    35. connect(jobb, SIGNAL(done(bool)), this, SLOT(grepdata()));
    36. }
    37. void DavListDir::run()
    38. {
    39. if (!urltogrep.isValid()) {
    40. quit();
    41. return;
    42. }
    43. jobb->start(); /* QHttp start request */
    44. exec();
    45.  
    46. while( waiting ) {
    47. decimalsec++;
    48. msleep(100);
    49. /* time out remote server! 2.5 sec .*/
    50. if (decimalsec > 25) {
    51. waiting = false;
    52. ned ="time_out";
    53. emit DataXml(ned);
    54. quit();
    55. }
    56. }
    57.  
    58. }
    To copy to clipboard, switch view to plain text mode 

  11. #9
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    8
    Thanked 541 Times in 521 Posts

    Default Re: QThread exec proplem to stop...

    No Patrick.
    Think at exec() as a loop ( actually it is one ) ). This loop exits when you call quit or exit.
    When the loop exits run() will continue with the next instructions - meaning the code that you have after exec().

    So there is no point in calling quit there. You shouldn't call emit either. Just pout the thread to sleep for as long as you have to.
    Qt Code:
    1. while(wainting)
    2. msleep( 200 );
    To copy to clipboard, switch view to plain text mode 
    You set waiting to false with from the GUI thread with a function that does only that : sets waiting to false( make sure "waiting" is volatile bool ). Therefore create another function in your thread that sets waiting to false.
    You won't need grepdata, or anything else.
    In the GUI thread, first call thread->quit(), and then, after some time( you must know when ), set waiting to false by calling that function.

    When it exits, it will emit finished(). In the slot that gets called by finished you must query the thread for "ned". This seems a reasonable solution to me.

  12. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,373
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: QThread exec proplem to stop...

    What does the while(waiting) loop do anyway? If you're spinning in a loop, why not use the one that is handled by exec()? You can use timers if you want to do something periodically. Seems that all you want is to react after 2.5s, so you can use a timer with such timeout and don't bother complicating things too much. And you can always stop the timer if you want to prevent it from timing out.

  13. #11
    Join Date
    May 2006
    Posts
    788
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows
    Thanks
    49
    Thanked 48 Times in 46 Posts

    Default Re: QThread exec proplem to stop...

    I tested this on bad url bad pass and correct param url is running ... on max 2sec. one dir list... one a clean xml or a message error..

    IMO: If troltech group know that the FTP password are visible clear, on place from QFtp QWebdav is born... and a remote dir model... must not write now..

    if you see other code leaks? ...

    Qt Code:
    1. class DavListDir : public QThread
    2. {
    3. Q_OBJECT
    4. public:
    5. void run();
    6. void SetUrl( QUrl u );
    7. signals:
    8. void DataXml(QString);
    9. void TimeEnd();
    10. private:
    11. QUrl urltogrep;
    12. QString ned;
    13. HTTP_propfind *jobb;
    14. bool waiting;
    15. int decimalsec;
    16. public slots:
    17. void grepdata();
    18. void httperror();
    19.  
    20. };
    21. void DavListDir::httperror()
    22. {
    23. emit DataXml(jobb->errorString());
    24. jobb->abort();
    25. exit();
    26. }
    27. void DavListDir::grepdata()
    28. {
    29. ned = jobb->GetDAVData();
    30. if (ned.size() > 0) {
    31. emit DataXml(ned);
    32. waiting = false;
    33. exit();
    34. return;
    35. }
    36. QTimer::singleShot(2000, this, SLOT(httperror()));
    37. }
    38. void DavListDir::SetUrl( QUrl u )
    39. {
    40. decimalsec = 0;
    41. waiting = true;
    42. urltogrep = QUrl(u);
    43. jobb = new HTTP_propfind(urltogrep); /* QHttp first setup header .... */
    44. connect(jobb, SIGNAL(done(bool)), this, SLOT(grepdata()));
    45. }
    46. void DavListDir::run()
    47. {
    48. if (!urltogrep.isValid()) {
    49. waiting = false;
    50. ned ="url_invalid";
    51. emit DataXml(ned);
    52. exit();
    53. return;
    54. }
    55. jobb->start(); /* QHttp start request */
    56. exec();
    57. }
    To copy to clipboard, switch view to plain text mode 

  14. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,373
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: QThread exec proplem to stop...

    I think your code is not very well designed, but if it works for you... hey, it's your application.

  15. #13
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,373
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: QThread exec proplem to stop...

    Quote Originally Posted by marcel View Post
    It will finish, but only if he calls quit() outside the thread ...
    It probably won't emit finished() then.

    Oh, BTW QThread::quit() is not virtual, neither is exit.
    Every slot is "implicitely" virtual if redeclared in a subclass. That's a side effect of how signals and slot mechanism works.

    So I'm not sure how correct it is to reimplement it. Anyway, if qt uses your class, it will call the base class version.
    No, it'll call the "youngest" implementation that has been declared as a slot. Of course this only applies to a situation when the method is called as a result of signal emission and not directly.

  16. The following user says thank you to wysota for this useful post:

    marcel (20th May 2007)

  17. #14
    Join Date
    May 2006
    Posts
    788
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows
    Thanks
    49
    Thanked 48 Times in 46 Posts

    Default Re: QThread exec proplem to stop...

    Quote Originally Posted by wysota View Post
    Hmmm.... This code is.... well... how should I say that.... hmm... incorrect
    This way the thread will never terminate... What's the point of spinning in the forever loop?
    not enter on forefer ... i delete...

  18. #15
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    8
    Thanked 541 Times in 521 Posts

    Default Re: QThread exec proplem to stop...

    Well, OK then.
    But remember, even if the code works right now, it is not conceptually correct.
    So, when you have the time, you should do a small redesign of your thread subclass.

    Regards

  19. #16
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    8
    Thanked 541 Times in 521 Posts

    Default Re: QThread exec proplem to stop...

    You shouldn't emit finished() from the thread.
    Wysota said that the parent must emit this signal - seem logical.

    Anyway, the code in run() that comes after exec() gets called only when you call quit() or exit().
    I suppose it is correct, but you shouldn't emit finished() here. Just let the thread exit from run() by itself, and it's parent will emit finished() when appropriate.

    Regards.

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.