简体   繁体   中英

Qt Worker thread - must I inherit for every specific task or can I use a callback?

In all examples of Qt QThread usage I see the same thing:

class MyThread : public QThread
{
/...
void run() { /...code
}
/...
};

So for every different task they make a new class. Is there a pecific reason why you can't have this:

class GenericThraed : public QThread
{
/...
void run() { function();
}

FunctionCallback function; //Pointer to a function that you pass to the thread before starting its execution
/...
};

I mean it looks like a way better alternative and way more robust. If you set the function pointer before the thread runs, there shouldn't be any issues, right?

QThread is not a thread, but more like a thread controller.

This article explains how to really use QThreads. Generally, you need not inherit from QThread, especially if the new thread requires an event loop.

One issue with your proposed method is that it doesn't take into account the thread affinity of objects which are accessed in the function callback.

For example: -

class SomeClass : public QObject
{
    Q_OBJECT

    public:
        void Increment() { m_index++; }

    private:
        int m_index = 0; // C++ 11 initialisation
};

Now, on the main thread....

SomeClass * pMyObject = new SomeClass;

If your function call back in the new thread has a pointer to pMyObject and calls its Increment function, it's likely to cause a fault, as the object's thread affinity is with the main thread, not the new thread.

So, you can move the object to the new QThread, but essentially, that's what the article I referenced above states: -

QThread* pThread = new QThread;
pMyObject->moveToThread(pThread);

So, what was the point of the functionCallback(?), as we can call the increment function either by connecting a signal and starting the thread:

connect(pThread, &QThread::run, pMyObject, &SomeObject::Increment);
pThread->start();

Or by invoking the method from the main thread

// object has been moved to another thread, but we can still call functions
// crossing the threads, by posting to the new thread's event queue
QMetaObject::invokeMethod(pMyObject, "increment", Qt::QueuedConnection);

Another benefit of using QThread without inheritance is that we can move more than a single instance of a QObject to the class, so there's not a one-to-one relationship between threads and objects; after all, there's usually little benefit having more threads than processor cores.

Although many of Qt's examples may inherit from QThread, in my opinion and one of the developers of QThread , it's not always the best method.

Yes, QThread lacks a std::thread -like way of simply launching a thread executing a function. It's not necessarily more robust, though. For instance you can't call exec() from within your function, if you ever need an event loop. (Note that if you just need a job queue QRunnable / QtConcurent::run might be a better fit).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM