Worker class for multithreading in Qt Code Answer

Hello Developer, Hope you guys are doing great. Today at Tutorial Guruji Official website, we are sharing the answer of Worker class for multithreading in Qt without wasting too much if your time.

The question is published on by Tutorial Guruji team.

I’ve been thinking about the worker class that can be used for parallel computing.

I wanted to avoid the situation when I have to move the worker to separate thread explicitly after creating the object i.e.:

Worker worker;
QThread thread;
worker.moveToThread(&thread);
thread.start();
worker.start();

This is the solution I came up with:

Header:

#include <QObject>
#include <QThread>

class ThreadedWorker : public QObject
{
    Q_OBJECT
public:
    explicit ThreadedWorker(QObject *parent = 0);
signals:
    void finished(ThreadedWorker* worker);
public slots:
    void start();
protected:
    virtual void run();
    QThread workerThread_;
    bool isRunning_;
};

Source:

#include "threadedworker.h"

ThreadedWorker::ThreadedWorker(QObject *parent) : QObject(parent)
{
    this->moveToThread(&this->workerThread_);
    this->workerThread_.start();
    this->isRunning_ = false;
}

void ThreadedWorker::start()
{
    if(!this->isRunning_)
     {
         this->isRunning_ = true;
         this->run();
     }
 }

 void ThreadedWorker::run()
 {
     // HERE GOES THE ACTUAL WORK FOR THE WORKER
     //
     //
     emit this->finished(this); // added to inform a controller object that the worker has finished
   }

UPDATED after comment by Zailborg:

So now I just create:

ThreadedWorker worker1;
ThreadedWorker worker2;

invoke their start() slots by some external signal and they run in parallel.

However my main concern is whether it is not a bad practice to put QThread workerThread_ as the member of ThreadedWorker class and moving the object to that thread in constructor.

Answer

whether it is not a bad practice to put QThread workerThread_ as the member of ThreadedWorker class

When an object is moved to its thread, the object and its children are moved. The children are the objects linked in the Qt parent child hierarchy when you pass a parent to a constructor of a QObject derived class, or call setParent.

In the case of a member pointer, such as a QThread pointer, it is not a “child” of the class. Therefore, when the ThreadedWorker object is moved to the new thread, this will work. However, problems can arise due to the confusion of thread affinity. The main object is moved to the the new thread, but holds a member pointer to an object whose thread affinity is different; the object pointed to by QThread*.

The code presented in the question doesn’t refer to a QThread pointer, but a QThread instance. With this in mind, consider the documentation for QObject::moveToThread when it states: –

Warning: This function is not thread-safe; the current thread must be same as the current thread affinity. In other words, this function can only “push” an object from the current thread to another thread, it cannot “pull” an object from any arbitrary thread to the current thread.

So, I suspect the design of QThread and QObject::moveToThread expects that the affinity of QThread is stable and will not be altered. By being a member of the object being moved, this is not going to be the case.

For this reason, I would say it is not a good idea to have a QThread instance as a member of a QObject and move the object to that thread.

If you’re going to use QThread, then I suggest reading and following the method as outlined in How to Really, Truly Use QThread.

In addition, it is often overlooked that the functionality of moveToThread allows a 1 to many relationship of QThread to QObject, so it is perfectly acceptable to create a QThread object and move multiple QObject instances to the new thread. Also, there is usually little benefit in creating more threads than available processor cores.

We are here to answer your question about Worker class for multithreading in Qt - If you find the proper solution, please don't forgot to share this with your team members.

Related Posts

Tutorial Guruji