Results 1 to 11 of 11

Thread: Some QThread questions

  1. #1
    Join Date
    May 2011
    Posts
    7
    Qt products
    Qt4
    Platforms
    Windows

    Default Some QThread questions

    Hi everyone,

    I have a computation that takes some time (let's say 200ms) and has to be executed all the time during program execution. Basically it takes some user input, does its 200ms work on it, delivers a result and instantly starts over again with the input data that may or may not have changed in the meantime. So I checked the Qt doc, put that stuff in a QThread subclass with it's run method looking basically like this:

    Qt Code:
    1. void myThread::run()
    2. {
    3. initSomeStuff();
    4. while(true)
    5. {
    6. performLongTask();
    7. }
    8. }
    To copy to clipboard, switch view to plain text mode 

    This means that the thread is basically busy all day with minimal interaction with the rest of the process, which should be fine as it's a worker thread. But after I start that thread it's slowing the responsibility my GUI op to the point of rendering it almost static - can anyone tell me what I missed? I checked the doc as well as some blogs and discussions including the often quoted "you're doing it wrong" article but ended up even more unsure about the proper approach. Maybe one of you can help me.

  2. #2
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: Some QThread questions

    So here what happens, as your QThread::run is conituous loop, it would never stop, as if it were the only thread running on the system, will always try to occupy the CPU, you should notice that CPU utilization goes >90% or even 100%. the best alternate is to have a defined cylce time / frequency at which this loop should execute.

    Lets see, as you said 200ms is the thread running time, it is better to have somthing >250ms as your cycle time, you can do this with simple QTimer, with QObject::timerEvent(), you may not need a QThread.

    If you have to use QThread, have a QTimer in the thread and then use its timerEvent() to performLongTask()

    Using a while(true) in QThread::run() is infact very bad idea. It will work, but it will the only think which will work on the system, every thing else will suffer.

  3. #3
    Join Date
    May 2011
    Posts
    7
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Some QThread questions

    Thank you.

    I have a multicore machine so I expected Windows to move the worker thread to another core to ensure GUI responsibility. Is there a manual way to achieve this? I already tried a timer with a delay of >200 ms but it resulted in a choppy behaviour where the 200ms that longTask needs to execute caused the GUI to stall for that time. As for the question concerning QThread: I dont'really need threads; what I need is a way of performing this constantly running computation (before you ask: I cannot split that task into smaller parts) in the background while providing the user with a smooth GUI.

  4. #4
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: Some QThread questions

    Ok, try adding QThread::msleep(10), in the while(true) loop, just to check the GUI response, its not very good programming, but may be used as short term workaround. (it's an old sleep trick)

    and about configuring a thread to run on a dedicated core, it is surely possible (may be at processes level), I am not aware of any Qt support for multi core, but native calls do exsist which I am not aware of again.

  5. #5
    Join Date
    May 2011
    Posts
    7
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Some QThread questions

    The msleep greatly increased GUI responsibility, but it's still far from being smooth. This may work for my development but I cant have a finished product be slow like this - especially since there re more time consuming features that I still have to add. But thank you, even this limited GUI response is better than what I had before.
    As for moving threads manually: This seems to require work with the win32 api, so I would have to check for the win32 implementation of the QThread class to get the thread's system handle. From my experience, mixing Qt and winapi on that low level usually means lots of trouble. Also most sources advice not to interfere with the OS if it comes to thread-core assignment. I have enough cores so I could even have one exclusively for my worker thread but I would like to stick with "good coding" practices before I start hacking around. I still believe that there is a Qt-compliant solution for my problem and that I am just using the QThread class in a wrong way.

  6. #6
    Join Date
    Sep 2009
    Location
    UK
    Posts
    2,447
    Thanks
    6
    Thanked 348 Times in 333 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Some QThread questions

    You might be using QThread the wrong way, post the code that is managing this thread.

    If you thread really needs 100% of the CPU whilst running you might want to change the priority of the thread so other threads in the system do not suffer.

  7. #7
    Join Date
    May 2011
    Posts
    7
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Some QThread questions

    As for now, I have no special managing yet. I start the thread right in the constructor of my base widget:

    myThreadInstance = new MyThread();
    myThreadInstance ->start();

    //edit:
    This actual thread is not even blocking the CPU, it's a manager for some OpenCL code that is basically making some stuff on the GPU. So most of the time it's just waiting for the GPU to finish it's work. I am currently working on making the GPU computation non-blocking so that the thread and the machine are not stalled, however I've had this issue with other threads that work heavily on the CPU so I would like to have a general approach towards the problem of threads that use a lot of CPU time.
    Last edited by justoit; 19th May 2011 at 17:49.

  8. #8
    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: Some QThread questions

    Try to do this something like :
    Qt Code:
    1. void myThread::run()
    2. {
    3. initSomeStuff();
    4. QTimer::singleShot(0,this,SLOT(oneLongTask());
    5. exec();//start event loop
    6. }
    7. void myThread::oneLongTask()
    8. {
    9. performLongTask();
    10. QTimer::singleShot(0,this,SLOT(oneLongTask());
    11. }
    To copy to clipboard, switch view to plain text mode 
    QTimer events are serviced after all another events.

  9. #9
    Join Date
    Oct 2009
    Posts
    483
    Thanked 97 Times in 94 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Some QThread questions

    @Lesiok

    There is a problem with your code. oneLongTask() being a slot of the myThread class, it will be run in the context of the thread in which the myThread instance lives (presumably the GUI thread), instead of the thread it manages.

    One possible solution is to move the slot to a custom class and to create an instance on the stack in the new thread:
    Qt Code:
    1. void myThread::run()
    2. {
    3. initSomeStuff();
    4. MyWorker worker;
    5. QTimer::singleShot(0,&worker,SLOT(oneLongTask());
    6. exec();//start event loop
    7. }
    8. void MyWorker::oneLongTask()
    9. {
    10. performLongTask();
    11. QTimer::singleShot(0,this,SLOT(oneLongTask());
    12. }
    To copy to clipboard, switch view to plain text mode 

    One may also use a plain QThread and use QObject::moveToThread() to have a MyWorker pushed to it.

    As for the problem of the OP, it is difficult to state on the matter without seeing the actual code. Also, why use a thread in the first place and not a higher-level function like QtConcurrent::run()?

  10. #10
    Join Date
    Jan 2010
    Posts
    9
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Some QThread questions

    As the previous poster pointed out, it is easier and cleaner to just create a worker-object that communicates only through signals and slots and move that to a QThread instance.

    You can ask it to start working either by connecting it to a "start working signal" that is emitted in the main thread or by invoking it indirectly from the main thread by using the static QMetaobject::invokeMethod() call.

    Something like:

    Qt Code:
    1. worker = new WorkerClass();
    2. connect(worker,SIGNAL(response(QString)),this,SLOT(response(QString)));
    3. QThread *t = new QThread();
    4. t->start(QThread::IdlePriority);
    5. worker->moveToThread(t);
    6. QMetaObject::invokeMethod(worker,"startWorking",Qt::QueuedConnection);
    To copy to clipboard, switch view to plain text mode 

  11. #11
    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: Some QThread questions

    Quote Originally Posted by yeye_olive View Post
    @Lesiok

    There is a problem with your code. oneLongTask() being a slot of the myThread class, it will be run in the context of the thread in which the myThread instance lives (presumably the GUI thread), instead of the thread it manages.
    I want to show only an idea of solution.

Similar Threads

  1. Replies: 2
    Last Post: 17th March 2011, 13:30
  2. Questions about QThread and Signals management
    By StanOfSky in forum Newbie
    Replies: 9
    Last Post: 6th November 2010, 14:36
  3. Replies: 1
    Last Post: 23rd April 2010, 13:23
  4. Replies: 4
    Last Post: 26th June 2008, 18:41
  5. Questions about QThread with QT
    By JonathanForQT4 in forum Qt Programming
    Replies: 1
    Last Post: 16th February 2007, 15:48

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.