This article详细说明QThread的“正确”用法
顺便提一下,这里要注意的一件非常重要的事情是你永远不应该在QObject类的构造函数中分配堆对象(使用new),因为这个分配然后在主线程上而不是在新的QThread实例上执行,意味着新创建的对象随后由主线程而不是QThread实例拥有。这将使您的代码无法正常工作。相反,在这种情况下,在主函数槽中分配这样的资源,例如process(),因为当调用该对象时,它将在新的线程实例上,因此它将拥有该资源。
我理解第一部分是堆对象的分配(从而运行构造函数)发生在创建QObject的线程中。之后才使用QThread :: moveToThread将其推送到QThread。
但是我不太明白所提到的所有权问题,特别是
意味着新创建的对象随后由主线程
拥有
肯定不是指资源的标准所有权,因为在Qt中可以通过父子机制轻松控制。
它是否意味着多线程(或QThread)的底层内存管理机制,尽管这只是我所知道的OS'线程实现的包装器?因为存储资源的每个线程都有不同的“内存段/缓存”?
如果是这种情况我可以看到问题,但我找不到完整的答案或解释。谢谢!
答案 0 :(得分:7)
它指的是QObjects存在于某些线程中的事实 - 默认情况下,创建它们的线程。 “实时”指的是QObject不是可重入的也不是线程安全的:QObject只能从它所在的线程中使用。
但是,建议是错误的。 是完全安全的class Foo : public QObject {
Q_OBJECT
Foo() {
m_suboject = new Bar(this);
m_other = new Fie("/dev/blah", this);
...
关键在于this
参数,这意味着子对象正确地为Foo实例的父级。因此,当你做
Foo *foo = new Foo;
foo->moveToThread(thread);
以“foo”为根的整个对象树将被移动到新线程中(moveToThread移动一个对象及其所有子对象)。