Results 1 to 17 of 17

Thread: QThread, moveToThread question

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Feb 2013
    Posts
    19
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default QThread, moveToThread question

    Hi together,

    I have some problems with understanding the behaviour of my following code...
    I tryed to udnerstand the Threading in Qt, so i found a nice youtube vid which i would like to share with you - its from Dario Freddi http://www.youtube.com/watch?v=MMFhc2jXzgw


    I Wrote a simple application to try movetothread methode, just 2 Workers and a QWidget class with a button. on button clicked worker 1 starts -> in its cTor it creates worker2 and waits of the finish signal from worker2. But some code say more than words so.
    i can post the whole simple project, but i dont know if its ok, so i just post the some few lines of code.

    QWidget:
    Qt Code:
    1. void Widget::on_btTest_clicked()
    2. {
    3. QTime time;
    4. time.start();
    5. worker1 *worker = new worker1;
    6. worker->doWork1();
    7. qDebug() << time.elapsed() << "mseconds" << "current time:" << time.currentTime().toString("hh:mm:ss:z")<< "worker1 result" << worker->getRes();
    8. }
    To copy to clipboard, switch view to plain text mode 

    Worker1:
    Qt Code:
    1. worker1::worker1(QObject *parent) :
    2. QObject(parent),
    3. m_classThread(new QThread),
    4. m_resultString("Hallo")
    5. {
    6. moveToThread(m_classThread);
    7. m_worker2 = new Worker2;
    8. //breaks the own event loop if worker 2 is finished
    9. connect(m_worker2, SIGNAL(workDone()), &wait, SLOT(quit()));
    10. connect(this, SIGNAL(startNow()), m_worker2, SLOT(doWork2()));
    11. m_classThread->start();
    12. }
    13.  
    14. void worker1::doWork1()
    15. {
    16. //starts worker2 und wartet auf sein finished
    17. qDebug() << Q_FUNC_INFO;
    18. emit startNow();
    19. wait.exec();
    20. }
    21.  
    22. QString worker1::getRes()
    23. {
    24. return m_resultString;
    25. }
    To copy to clipboard, switch view to plain text mode 

    Worker2:
    Qt Code:
    1. Worker2::Worker2(QObject *parent) :
    2. QObject(parent),
    3. m_classThread(new QThread),
    4. m_resultString("123")
    5. {
    6. moveToThread(m_classThread);
    7. tima.setInterval(5000);
    8. tima.start();
    9. m_classThread->start();
    10. }
    11.  
    12. void Worker2::doWork2()
    13. {
    14. qDebug() << Q_FUNC_INFO;
    15. // create a event loop for the timer to be finished
    16. QEventLoop wait;
    17. connect(&tima, SIGNAL(timeout()), &wait, SLOT(quit()));
    18. wait.exec();
    19. emit workDone();
    20.  
    21. }
    To copy to clipboard, switch view to plain text mode 



    Results in the Debug frame:
    Qt Code:
    1. void worker1::doWork1()
    2. void Worker2::doWork2()
    3. void worker1::doWork1()
    4. void Worker2::doWork2()
    5. 5003 mseconds current time: "15:35:22:36" WIDGET: worker one "Hallo"
    6. 7204 mseconds current time: "15:35:22:36" WIDGET: worker one "Hallo"
    To copy to clipboard, switch view to plain text mode 


    So here is my missunderstood/question -> if i click the button twice with a simple delay of 2 seconds, why get i the results at the same time? Why i dont get the debug msg of the first click on the button from(worker.getRes() (in the widget class) not 2 seconds earlier than the msg of the 2nd click?

    If I may suggest, then I would argue that the problem is that the queue for the widget/main thread queue is accessed when the 2nd click -> workers are finished? So the first debug msg got queued at the mainthread and fired when the last work is done? But i dont get it exactly whats the problem here.

    It would be very nice if s.o can explain me the above behaviour. An it would be really nice , to see how to solve this "problem". thanks!
    (if u want me to post the project as attachement - just tell me....)

    TIA Anenja!

  2. #2
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: QThread, moveToThread question

    Hi, in worker1::doWork1(): what is "wait"?

    Further, when you use moveToThread, you have to call slots by using signals. If you call them via "->" the function is executed in the same thread as the caller. (In the video he is connecting the QThread::started() with a moved object slot.). Also if you move Worker2 to a Thread, there is - I think, since I am also no thread expert - no need for an event loop inside.

  3. #3
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QThread, moveToThread question

    Quote Originally Posted by Lykurg View Post
    Also if you move Worker2 to a Thread, there is - I think, since I am also no thread expert - no need for an event loop inside.
    The base implementation of QThread::run() already runs an event loop (see QThread::exec(), QThread::quit()), but a nested event loop is not wrong either. Depends on whether you want to keep the thread itself running.

    I agree that worker1->doWork1() looks wrong since it totally bypasses the first thread. One would expect that the widget's code connects to some sort of result signal and then starts the first thread.

    Cheers,
    _

  4. #4
    Join Date
    Feb 2013
    Posts
    19
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread, moveToThread question

    Hi, in worker1::doWork1(): what is "wait"?
    Thanks for your help!
    wait is just an eventLoop.
    I Dont subclass qthread so i need a own eventloop if i want to wait for s.th at this point within this thread.

    I agree that worker1->doWork1() looks wrong since it totally bypasses the first thread
    Thanks for your help!
    Ok i understand this. Still if i connect doWork1() to the thread started() signal, in its cTor it dont fix the behaviour.


    What i think what happens:
    I create a worker object on bt_clicked() in the MainThread, then in workers cTor the object is moved to it´s own thread, then in the cTor of worker1 I create worker2 (in the mainthread - cause the thread of worker 1 hasn´t started yet, then in workers2 cTor the object is moved to its own thread. So, worker1 life in its thread an worker 2 does. worker 1 waits in it´s own QEventloop for worker2 to be finished.
    the debug msg of the threadID´s confirm the things i wrote above.

    i fix the code so only signal/slots will be used...
    Qt Code:
    1. //breaks the own event loop if worker 2 is finished
    2. connect(m_worker2, SIGNAL(workDone()), &wait, SLOT(quit()));
    3. // signal startNow is emitted in doWork1()
    4. connect(this, SIGNAL(startNow()), m_worker2, SLOT(doWork2()));
    5. connect(m_classThread, SIGNAL(started()), this, SLOT(doWork1()));
    6. m_classThread->start();
    7. wait.exec();
    To copy to clipboard, switch view to plain text mode 

    QWidget:
    Qt Code:
    1. ....
    2. worker1 *worker = new worker1;
    3. qDebug() << "this debug msg will executed if worker1 is finished ";
    4. ....
    To copy to clipboard, switch view to plain text mode 


    I really try to solve this and understand it - but i dont know if i am right here.
    I click the button and the eventqueue of worker1 blocks the go on in the next line of code (in slot bt_clicked()) - thats ok i can understand this, but if i click this button again why are the debug mgs fired at the same time together?
    if I add an other button on the widget i can click this bt while the threads are running (on click just show a debug msg) and it is fired instantly.

    I hope u can follow/understand me, my english is not really good -.-

    debug console:
    Qt Code:
    1. Worker1 created()
    2. "another widget bt bt_clickedNew tho show just a debug msg"
    3. Worker1 created()
    4. "another widget bt bt_clickedNew tho show just a debug msg"
    5. 5002 mseconds current time: "12:40:14:355" WIDGET: worker one QThread(0x851cb90) "Hallo"
    6. 6987 mseconds current time: "12:40:14:355" WIDGET: worker one QThread(0x840ce58) "Hallo"
    To copy to clipboard, switch view to plain text mode 


    Thanks for your help!
    Last edited by Anenja; 24th February 2013 at 11:47.

  5. #5
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QThread, moveToThread question

    why don't you use your debugger and some breakpoints to see what is happening?
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  6. #6
    Join Date
    Feb 2013
    Posts
    19
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread, moveToThread question

    amleto

    Re: QThread, moveToThread question
    why don't you use your debugger and some breakpoints to see what is happening?
    Thanks for your help.
    Hi, i tryed to debug it, but i dont get anything useful information out of it

    i really dont get the point where i did the mistake or the missunderstand happens. perhaps s.o can have a quick look at it -> i put the project as attachment.

    Thanks again, really nice to get all ur help.!
    Attached Files Attached Files

  7. #7
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QThread, moveToThread question

    If you dont get anything useful then add more. Learning how to debug is not optional for programmers.

    What you have is frankly a mess of threads and timers in object that aren't moving in the same threads as their owners etc. Why don't you time how long worker 1 takes. It should be about 5s, right? Sometimes for me it is 5s, sometimes 7s. You should look into that if you are doing this just as problem solving. If you want to write some code for learning purpose, I suggest you throw away what you've done and write it properly.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  8. #8
    Join Date
    Feb 2013
    Posts
    19
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread, moveToThread question

    Quote Originally Posted by amleto View Post
    If you dont get anything useful then add more. Learning how to debug is not optional for programmers.

    What you have is frankly a mess of threads and timers in object that aren't moving in the same threads as their owners etc. Why don't you time how long worker 1 takes. It should be about 5s, right? Sometimes for me it is 5s, sometimes 7s. You should look into that if you are doing this just as problem solving. If you want to write some code for learning purpose, I suggest you throw away what you've done and write it properly.
    Thank you amleto.

    i checked the timer variable and its thread and u are right the timer is in the mainthread home created and the object itself is moved to another thread.
    i will debug it harder and try to rewrite it properly.

    a question i got:
    Worker *work = new Worker; //created in the current thread and ALL membervars are also created in this thread
    If u now use moveToThread(t1) -> are the member vars still in the "old" thread, so is this a problem ?

    TIA

  9. #9
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QThread, moveToThread question

    all member vars of the instance that have not had their parent set to the instance will not move when the instance is moved.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  10. #10
    Join Date
    Feb 2013
    Posts
    19
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread, moveToThread question

    amleto

    Re: QThread, moveToThread question
    all member vars of the instance that have not had their parent set to the instance will not move when the instance is moved.
    ok thanks i got this.

    I also got my logical Problem in the above code. Debugger helps me to get it

    I Created an event loop in the cTor of Worker1 -> eventloop is created in the mainthread and is not moved (i think u cant move this loop cause it makes no sense or? - if i create a loop in a slot and moved the object in the ctor all is fine, the loop is created in the object thread <-parent is the object ....) The loop in the cTor stops the application to move on in the code (sry for this explanation but i really dont know how to explain this). what i mean is:
    Qt Code:
    1. line 9: ....
    2. line 10: Worker1 * worker = new Worker1; // at this point the cTor loop stops the further going to line 11 until the loop is finished
    3. line 11: qDebug() << "....."
    To copy to clipboard, switch view to plain text mode 

    So if i am right, the eventloop which "lives" in the mainthread created in the cTor (line 10) is the reason why the qDebug msg are fired at the same time - if i click the button twice.
    This i cause the eventloop of worker1 is started in the cTor, after 5 seconds worker2 quits this loop, but the new click on the button creates a new eventloop which again blocks the go on to line 11 (-> there can only be one eventloop in a thread right?) so after the new worker1 created by clicking the button again "reopens" the event queue (by creating a new in the mainthread) - if worker2 is now finished this eventloop is leaved and the qDebug msgs appear both at the same time.

    It would be really nice if s.o can tell me if iam right - this is the result i got from debugging and this behaviour makes sense to me.

    Thanks again and have a nice sunday

  11. #11
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QThread, moveToThread question

    there can be many event loops in a thread, and this is in fact your problem. If this didn't happen, you wouldn't be able to press the button for a second time since your worker1 is blocking the main thread. The only reason the gui remains responsive is because you start a second event loop in the main thread. When you get 'recursive' event loops, Qt does some managing of which signals and slots to process based on recursion level (I think) - this will be why your signal/slot from the first button press are delayed until after the second button press's signals have been processed.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

Similar Threads

  1. Replies: 11
    Last Post: 12th September 2012, 16:25
  2. Replies: 1
    Last Post: 4th September 2012, 14:13
  3. Replies: 2
    Last Post: 17th March 2011, 13:30
  4. QThread Question
    By ionutdanila in forum Newbie
    Replies: 7
    Last Post: 6th January 2011, 07:23
  5. basic qthread question
    By zl2k in forum Qt Programming
    Replies: 2
    Last Post: 9th September 2008, 21:43

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.