Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Using QThread
QtWS25 Last Chance

Using QThread

Scheduled Pinned Locked Moved General and Desktop
10 Posts 6 Posters 6.9k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    jdarnold
    wrote on last edited by
    #1

    I have a question about "good practices" using QThread. I have a couple of related functions that I would like to run in their own thread. These function calls are not frequent, but often enough. Rather than create a QThread object for each of these functions, I created a single QThread object. Each method sets a function index and starts the thread. The run() function of the thread checks the function index, then calls that function.

    @void myThread::run()
    {
    switch ( _function )
    {
    case FUNC1:
    func1();
    break;
    case FUNC2:
    func2();
    break;
    }
    void myThread::callFunc1()
    {
    _function = FUNC1;
    start();
    }

    void myThread::callFunc2()
    {
    _function = FUNC2;
    start();
    }@

    Is this a reasonable way to do this? How expensive is start() - should I use a QWaitCondition instead and put the run() function asleep waiting for the condition?

    1 Reply Last reply
    0
    • I Offline
      I Offline
      iunknwn
      wrote on last edited by
      #2

      Look into QThreadPool and QRunnable.

      Qt maintains a global instance of QThreadPool with ideal threadcount. Thread creation is expensive and hence QThreadpool would provide you with threads which can run your runnables and go back to threadpool. So I'd suggest make your funcs runnables and use it with global qhreadpool instance.

      Vista x64 with Qt 4.8.2 and VS2010

      1 Reply Last reply
      0
      • J Offline
        J Offline
        jdarnold
        wrote on last edited by
        #3

        Thx for the idea. I will look into QThreadPool.

        1 Reply Last reply
        0
        • M Offline
          M Offline
          markus.liebe
          wrote on last edited by
          #4

          Did you have a look at "QtConcurrent::run()":http://doc.qt.nokia.com/4.7-snapshot/qtconcurrentrun.html#run ?

          Allows you to run a given function in a Thread. And I think it uses the QThreadPool as well.

          Regards,
          Markus

          1 Reply Last reply
          0
          • C Offline
            C Offline
            ckakman
            wrote on last edited by
            #5

            Why don't you make your function public slots of the QThread subclass? You should call, say , in the constructor of the subclass

            @this>moveToThread(this);@

            This way, your slots would run in another thread than the callee's thread. As an additional benefit, you can enjoy various Signal-Slot connection types (Qt::DirectConnection, Qt::BlockingQueuedConnection etc) besides the default Qt::AutoConection, if needed.

            You wouldn't need to reimplement QThread::run().

            1 Reply Last reply
            0
            • F Offline
              F Offline
              Franzk
              wrote on last edited by
              #6

              "You're doing it wrong...":http://labs.qt.nokia.com/2010/06/17/youre-doing-it-wrong/

              The proper fix is to make an object and move that to a QThread. You cannot move a QThread into the thread it manages.

              "Horse sense is the thing a horse has which keeps it from betting on people." -- W.C. Fields

              http://www.catb.org/~esr/faqs/smart-questions.html

              1 Reply Last reply
              0
              • D Offline
                D Offline
                DenisKormalev
                wrote on last edited by
                #7

                Franzk, technically you can do it, of course not in constructor, but after thread was started.

                1 Reply Last reply
                0
                • F Offline
                  F Offline
                  Franzk
                  wrote on last edited by
                  #8

                  Although technically possible, it would still be a bad idea. Bradley states the following:

                  bq. My #1 biggest gripe with this code is moveToThread(this); I see so many people using this without understanding what it does. What does it do, you ask? The moveToThread() function tells Qt to ensure that event handlers, and by extension signals and slots, are called from the specified thread context. QThread is the thread interface, so we’re telling the thread to run code “in itself”. We’re also doing this before the thread is running as well. Even though this seems to work, it’s confusing, and not how QThread was designed to be used (all of the functions in QThread were written and intended to be called from the creating thread, not the thread that QThread starts).

                  Using stuff in a different way than intended usually leads to confusion and without any doubt to errors in the future. To me it would be like placing a table on top of it's own table top...

                  "Horse sense is the thing a horse has which keeps it from betting on people." -- W.C. Fields

                  http://www.catb.org/~esr/faqs/smart-questions.html

                  1 Reply Last reply
                  0
                  • C Offline
                    C Offline
                    ckakman
                    wrote on last edited by
                    #9

                    It is possible to do it in the constructor. I have done it many many times, and it works perfectly. Changing the object's thread affinity and starting the thread are two diferent matters.

                    I have also read the blog entry Frankz quotted. However check what is recommended in the official Qt book "C++ GUI Programming with Qt 4, Second Edition". They recommend using QThread subclasses:

                    bq. Providing multiple threads in a Qt application is straightforward: We just subclass QThread and reimplement its run() function.

                    This, although not the same as moveToThread(this) business,
                    contradicts Bradley's interface separation argument. What do we do now?

                    As when to do this: Sometimes, for me most of the times, you want an object to run all of its functions in another thread: Image processing, logging, image acquisition, io, network comm etc. I want only one instance of an object to run in another thread.

                    UPDATE: The book covers Qt 4.3, Bradley says there has been changes at version 4.4 that makes using QThread without subclassing it possible. So, I agree with the comments above and recommend using QThread as Bradley suggested:

                    @myObject->moveToThread(someQthreadInstancePointer)@

                    Sorry for the confusion I've caused.

                    1 Reply Last reply
                    0
                    • J Offline
                      J Offline
                      jdarnold
                      wrote on last edited by
                      #10

                      Excellent discussion! Thanks for all the options. There's a few other conditions I have on this problem, but looks solvable at a much higher level than I'm using.

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved