【发布时间】:2016-12-01 09:37:06
【问题描述】:
故事:
我对应用程序中的每个“长”操作都使用 QtConcurrent API。 它工作得很好,但我在创建 QObjects 时遇到了一些问题。
考虑这段代码,它使用一个线程来创建一个“Foo”对象:
QFuture<Foo*> = QtConcurrent::run([=]()
{
Data* data = /*long operation to acquire the data*/
Foo* result = new Foo(data);
return result;
});
它工作得很好,但是如果“Foo”类是从 QObject 类派生的,那么“结果”实例属于创建该对象的 QThread。
因此,要在“结果”实例中正确使用信号/插槽,应该执行以下操作:
QFuture<Foo*> = QtConcurrent::run([=]()
{
Data* data = /*long operation to acquire the data*/
Foo* result = new Foo(data);
// Move "result" to the main application thread
result->moveToThread(qApp->thread());
return result;
});
现在,一切都按预期进行,我认为这是正常行为和名义上的解决方案。
问题:
我有很多这种代码,有时创建对象,也可以创建对象。它们中的大多数都是通过“moveToThread”调用正确创建的。
但有时,我会错过一个“moveToThread”调用。
然后,很多事情看起来都不起作用(因为这个对象插槽被“损坏”),没有任何 Qt 警告。
现在,我有时会花很多时间来弄清楚为什么某些东西不起作用,然后才明白这只是因为不再在特定对象实例上调用插槽。
问题:
有什么方法可以帮助我防止/检测/调试这种情况? 例如:
- 每次删除 QThread 时都会记录警告,但有属于它的活着的对象?
- 每次向被删除 QThread 的对象发出信号时都会记录警告?
- 每次向对象(在另一个线程中)发出信号并且在超时前未处理时都会记录警告?
谢谢
【问题讨论】:
-
Foo类型QObjects 是否有理由必须具有非主线程亲和性(我认为您所说的“属于”是什么意思)? -
第三题重复;请删除它。您在问如何检测挂起的事件循环 - 这与是否发出信号无关。见here。
标签: c++ qt qthread qobject qtconcurrent