繁体   English   中英

Qt Worker线程-必须为每个特定任务继承还是可以使用回调?

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

在所有Qt QThread用法示例中,我都看到了相同的东西:

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

因此,对于每一项不同的任务,他们都会开设一个新的班级。 是否有特定原因导致您无法使用此功能:

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

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

我的意思是,它看起来像是一种更好的替代方法,并且更加强大。 如果在线程运行之前设置函数指针,应该不会有任何问题,对吗?

QThread不是线程,而更像是线程控制器。

本文介绍了如何真正使用QThreads。 通常,您不需要从QThread继承,尤其是在新线程需要事件循环的情况下。

所提出的方法的一个问题是它没有考虑在函数回调中访问的对象的线程亲和性。

例如: -

class SomeClass : public QObject
{
    Q_OBJECT

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

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

现在,在主线程上。

SomeClass * pMyObject = new SomeClass;

如果在新线程中回调的函数具有指向pMyObject的指针并调用其Increment函数,则很可能会导致错误,因为对象的线程亲和力与主线程(而不是新线程)有关。

因此,您可以将对象移动到新的QThread,但从本质上讲,这就是我上面引用的文章所指出的:-

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

因此,functionCallback(?)的意义何在,因为我们可以通过连接信号并启动线程来调用增量函数:

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

或者通过从主线程调用方法

// 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);

使用不继承的QThread的另一个好处是,我们可以将多个QObject实例移到该类上,因此线程与对象之间不存在一对一的关系。 毕竟,拥有比处理器核心更多的线程通常没有什么好处。

尽管Qt的许多示例可能都继承自QThread,但我认为还是QThread开发人员之一 ,它并不总是最好的方法。

是的, QThread缺少QThread std::thread的方法,它只是启动执行函数的线程。 不过,它不一定更健壮。 例如,如果您需要事件循环,则无法从函数内部调用exec() (请注意,如果只需要一个作业队列QRunnable / QtConcurent::run可能更合适)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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