#include<bits/stdc++.h>#include<QCoreApplication>#include<QDebug>#include<QString>#include<QThread>usingnamespace std;classMyWorker:publicQObject{
Q_OBJECT
public:MyWorker( QString _name ):name( _name ){}public slots:voiddo_work(){qDebug()<< name <<" is now working in "<<QThread::currentThread()<<"\n";}voidgo_home(){this->moveToThread(QCoreApplication::instance()->thread());}private:
QString name ="plain worker";};classMyThread:publicQThread{
Q_OBJECT
public:MyThread( QThread* controller ){assert(currentThread()==QCoreApplication::instance()->thread());this->controller = controller;qDebug()<<"native worker is originally working on: \n";
nativeWorker.do_work();// Assignation must be done in the original thread of the QObjectqDebug()<<"Assign native worker to the factory. \n";
nativeWorker.moveToThread(this);connect( controller,&QThread::started,&nativeWorker,&MyWorker::do_work );
nativeWorkerChild =newMyWorker("Child born in factory building stage in main thread");
nativeWorkerChild->do_work();}private:voidrun()override{qDebug()<<"Factory running ---------------";
nativeWorkerChild =newMyWorker("Next-generation worker born in factory running");
nativeWorkerChild->do_work();connect( controller,&QThread::started, nativeWorkerChild,&MyWorker::do_work );exec();}
QThread* controller;
MyWorker nativeWorker{"nativeWorker"},*nativeWorkerChild;};intmain(int argc,char* argv[]){
QCoreApplication app( argc, argv );qDebug()<<"";
MyWorker mainThreadWorker("mainThreadWorker");
mainThreadWorker.do_work();
emit mainThreadWorker.do_work();
QThread threadController;
MyThread factory(&threadController );
factory.start();qDebug()<<"Assign main thread worker to the factory";qDebug()<<"";
mainThreadWorker.moveToThread(&factory );QObject::connect(&threadController,&QThread::started,[&](){assert(QThread::currentThread()==&threadController );});QObject::connect(&threadController,&QThread::started,&mainThreadWorker,&MyWorker::do_work );
threadController.start();QThread::sleep( chrono::milliseconds(200));qDebug()<<"Main thead is busy, calling mainThreadWorker to another factory two times-----------\n";
QThread urgentBussiness;QObject::connect(&urgentBussiness,&QThread::started,[&](){
MyWorker lambdaWorker("Lambda worker");
lambdaWorker.do_work();});QObject::connect(&urgentBussiness,&QThread::started,&mainThreadWorker,&MyWorker::do_work, Qt::DirectConnection );QObject::connect(&urgentBussiness,&QThread::started,&mainThreadWorker,&MyWorker::do_work );
urgentBussiness.start();QThread::sleep( chrono::milliseconds(200));QObject::connect(&threadController,&QThread::finished,&mainThreadWorker,&MyWorker::go_home );QObject::connect(&factory,&QThread::finished,&mainThreadWorker,&MyWorker::do_work );qDebug()<<"Controller is dead----------\n";
threadController.quit();
threadController.wait();assert( mainThreadWorker.moveToThread(QCoreApplication::instance()->thread()));
factory.quit();
factory.wait();QThread::sleep( chrono::milliseconds(200));return app.exec();}#include"ThreadAffinity.moc"
Output
"mainThreadWorker" is now working in QThread(0x5a533fe56690, name = "Qt mainThread")
"mainThreadWorker" is now working in QThread(0x5a533fe56690, name = "Qt mainThread")
native worker is originally working on:
"nativeWorker" is now working in QThread(0x5a533fe56690, name = "Qt mainThread")
Assign native worker to the factory.
"Child born in factory building stage in main thread" is now working in QThread(0x5a533fe56690, name = "Qt mainThread")
Assign main thread worker to the factory
Factory running ---------------
"Next-generation worker born in factory running" is now working in MyThread(0x7fffd070c0f0)
"nativeWorker" is now working in MyThread(0x7fffd070c0f0)
"mainThreadWorker" is now working in MyThread(0x7fffd070c0f0)
"Next-generation worker born in factory running" is now working in MyThread(0x7fffd070c0f0)
Main thead is busy, calling mainThreadWorker to another factory two times-----------
"Lambda worker" is now working in QThread(0x7fffd070c090)
"mainThreadWorker" is now working in QThread(0x7fffd070c090)
"mainThreadWorker" is now working in MyThread(0x7fffd070c0f0)
Controller is dead----------
"mainThreadWorker" is now working in QThread(0x5a533fe56690, name = "Qt mainThread")
^C