在所有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 的指针并调用其增量函数,则可能会导致错误,因为对象的线程相关性与主线程有关,而不是与新线程相关。
因此,您可以将对象移动到新的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
缺少一种类似std::thread
的方式来简单地启动执行函数的线程。不过,它不一定更强大。例如,如果您需要事件循环,则无法从函数中调用exec()
。(请注意,如果您只需要一个作业队列QRunnable
/QtConcurent::run
可能更适合)。