Qt Multithreading and Concurrency

Qt Multithreading and Concurrency

There are multiple ways to utilize threads in Qt. Here I show 5 ways:

1) First method is very similar to STD C++.

#include <QCoreApplication>
void hello()
{
? ? QThread::currentThread()->setObjectName("Worker Thread");
? ? qInfo() << "Hello From Worker Thread!" << QThread::currentThread();
? ? QThread::msleep(500);
? ? qInfo() << "Goodbye From Worker Thread!" << QThread::currentThread();
}
int main(int argc, char *argv[])
{
? ? QCoreApplication a(argc, argv);
? ? QThread::currentThread()->setObjectName("Main Thread");


? ? QThread *thread = QThread::create(hello);
? ? thread->start();


? ? qInfo() << "Hello From Main Thread" << QThread::currentThread();
? ? QThread::msleep(1000);
? ? qInfo() << "Goodbye From Main Thread" << QThread::currentThread();

? ? delete(thread);

? ? return a.exec();
}        

2) For second method, the Concurrent library must be added to CMake:

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Concurrent)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Concurrent)

target_link_libraries(lsn2QtConcurrent Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Concurrent)        



#include <QCoreApplication>
#include <QtConcurrent>

void hello()
{
? ? QThread::currentThread()->setObjectName("Worker Thread");
? ? qInfo() << "Hello From Worker Thread!" << QThread::currentThread();
? ? QThread::msleep(2000);
? ? qInfo() << "Goodbye From Worker Thread!" << QThread::currentThread();
}


int main(int argc, char *argv[])
{
? ? QCoreApplication a(argc, argv);
? ? QThread::currentThread()->setObjectName("Main Thread");


? ? QFuture<void> future = QtConcurrent::run(&hello);


? ? qInfo() << "Hello From Main Thread" << QThread::currentThread();
? ? QThread::msleep(500);
? ? qInfo() << "Blocking ..." << QThread::currentThread();
? ? future.waitForFinished();
? ? qInfo() << "Goodbye From Main Thread" << QThread::currentThread();


? ? return a.exec();
}        

3) For third method, worker class must be added. Add new class named "Worker" and select QObject as Base class:

#include <QObject>
#include <QDebug>
#include <QThread>


class Worker : public QObject
{
? ? Q_OBJECT
public:
? ? explicit Worker(QObject *parent = nullptr);
? ? ~Worker();


signals:


public slots:
? ? void work();
};
        


#include "worker.h"

Worker::Worker(QObject *parent)
? ? : QObject{parent}
{
}

Worker::~Worker()
{
}

void Worker::work()
{
? ? QThread::currentThread()->setObjectName("Worker Thread");
? ? qInfo() << "Hello From Worker Thread!" << QThread::currentThread();
? ? QThread::msleep(1000);
? ? qInfo() << "Goodbye From Worker Thread!" << QThread::currentThread();
}

        


#include <QCoreApplication>
#include <QThread>
#include "worker.h"
int main(int argc, char *argv[])
{
? ? QCoreApplication a(argc, argv);
? ? QThread::currentThread()->setObjectName("Main Thread");


? ? QThread thread;
? ? thread.setObjectName("Worker Thread");


? ? Worker *worker = new Worker();
? ? worker->moveToThread(&thread);
? ? thread.connect(&thread,&QThread::started, worker, &Worker::work);
? ? thread.start();
? ? qInfo() << "Hello From Main Thread" << QThread::currentThread();
? ? QThread::msleep(500);
? ? qInfo() << "Goodbye From Main Thread" << QThread::currentThread();

? ? return a.exec();
}        

?

4) There is more polished way of doing third method. It's to use QThread as a base class for "Worker" class and then inserting run function. Add new class named "Worker" and select <Custom> QThread as a base class:

#include <QThread>
#include <QDebug>


class Worker : public QThread
{
public:
? ? explicit Worker(QObject *parent = nullptr);

? ? // QThread interface
protected:
? ? void run() override;
};        


#include "worker.h"
#include "qdebug.h"


Worker::Worker(QObject *parent)
? ? : QThread{parent}
{


}


void Worker::run()
{
? ? QThread::currentThread()->setObjectName("Worker Thread");
? ? qInfo() << "Hello From Worker Thread!" << QThread::currentThread();
? ? QThread::msleep(1000);
? ? qInfo() << "Goodbye From Worker Thread!" << QThread::currentThread();
}        


#include <QCoreApplication>
#include <QThread>
#include "worker.h"


int main(int argc, char *argv[])
{
? ? QCoreApplication a(argc, argv);

? ? QThread::currentThread()->setObjectName("Main Thread");

? ? Worker *worker = new Worker();
? ? worker->start();
? ? qInfo() << "Hello From Main Thread" << QThread::currentThread();
? ? QThread::msleep(500);
? ? qInfo() << "Goodbye From Main Thread" << QThread::currentThread();

    return a.exec();
}        


5) The last method uses QThreadPool and QRunnable. Add new class named "Worker" and select QRunnable as its base class then insert run function of QRunnable class.

#include <QRunnable>

class Worker : public QRunnable
{
public:
? ? Worker();

? ? // QRunnable interface
public:
? ? void run() override;
};        


#include "worker.h"
#include "qdebug.h"

Worker::Worker()
{
}

void Worker::run()
{
? ? QThread::currentThread()->setObjectName("Worker Thread");
? ? qInfo() << "Hello From Worker Thread!" << QThread::currentThread();
? ? QThread::msleep(1000);
? ? qInfo() << "Goodbye From Worker Thread!" << QThread::currentThread();
}        


#include <QCoreApplication>
#include <QThreadPool>
#include "worker.h"

int main(int argc, char *argv[])
{
? ? QCoreApplication a(argc, argv);


? ? QThread::currentThread()->setObjectName("Main Thread");


? ? QThreadPool thread;
? ? thread.setObjectName("Worker Thread");


? ? Worker *worker = new Worker();
? ? thread.start(worker);
? ? qInfo() << "Hello From Main Thread" << QThread::currentThread();
? ? QThread::msleep(500);
? ? qInfo() << "Goodbye From Main Thread" << QThread::currentThread();

? ? return a.exec();
}        

I tried to make examples as simple as possible so there are some caveats regarding pointers. One can use QScopedPointer<> or signal and slots with deleteLater() or setAutoDelete(true) options as they relish.

要查看或添加评论,请登录

Mohammad Daneshgar的更多文章

  • STM32 Bare-Metal

    STM32 Bare-Metal

    Microcontroller From scratch with STM32 : Lesson One In lesson zero we did a simple example using HAL drivers. Here we…

  • STM32 From scratch

    STM32 From scratch

    Microcontroller From scratch with STM32 : Lesson Zero First off you have to install STM32CubeIDE and have a STM32…

  • Throws and Self defense

    Throws and Self defense

    I've been practicing martial arts for more than two decades. I still train two times a day, one-hour session dedicated…

  • 17 Things To Do After After Installing Ubuntu 20.04

    17 Things To Do After After Installing Ubuntu 20.04

    Create Progs (working directory for programming) and Books $ mkdir Progs Books 2. Install vim Text Editor $ sudo apt…

    4 条评论
  • VHDL & C++

    VHDL & C++

    This prelude is neither about VHDL nor about C++ indeed it's about "to add some C++ codes to VHDL codes" or to put it…

    1 条评论
  • ???? ?? ?????? ??? ? ??? ??? ?? ?? ?? ?????

    ???? ?? ?????? ??? ? ??? ??? ?? ?? ?? ?????

    ?? ??? ??? ???? ??? ??? ? ??? ???????? ?? ???? ?? ????? ????? ?? ?? ???? ???. ?? ????? ?? ????? ?? ???? ???? ???? ?????…

  • Linux & EDA

    Linux & EDA

    Using Linux as your quotidian OS isn't just for computer savvies, coders or hackers, Linux is also the best bet of…

    1 条评论
  • From 5.6-liter V8 Sedan to 2.0-liter I4 crossover

    From 5.6-liter V8 Sedan to 2.0-liter I4 crossover

    I'm #survivalist and the catastrophe I'm preparing for is 2.0-liter I4 SUVs and illiterate celebrities being professors…

  • Smoldering Passion

    Smoldering Passion

    At one time, this was an adage to live by: follow your passion. At present, they say it’s “Awful”, “Crappy”, “Dump”…

社区洞察

其他会员也浏览了