Qt thread affinity.

Qt thread affinity.

Test case

#include <bits/stdc++.h>

#include <QCoreApplication>
#include <QDebug>
#include <QString>
#include <QThread>
using namespace std;

class MyWorker : public QObject {
    Q_OBJECT
   public:
    MyWorker( QString _name ) : name( _name ) {}
   public slots:
    void do_work() {
        qDebug() << name << " is now working in " << QThread::currentThread() << "\n";
    }
    void go_home() {
        this->moveToThread( QCoreApplication::instance()->thread() );
    }

   private:
    QString name = "plain worker";
};

class MyThread : public QThread {
    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 QObject
        qDebug() << "Assign native worker to the factory. \n";
        nativeWorker.moveToThread( this );
        connect( controller, &QThread::started, &nativeWorker, &MyWorker::do_work );

        nativeWorkerChild = new MyWorker( "Child born in factory building stage in main thread" );
        nativeWorkerChild->do_work();
    }

   private:
    void run() override {
        qDebug() << "Factory running ---------------";
        nativeWorkerChild = new MyWorker( "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;
};

int main( 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rabxs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值