我正在考虑如何将结果数据从某个工作线程传回客户端而不进行复制。 Worker 住在其他线程中,而 BigData 继承了 QObject。我的想法是改变数据的所有权:
class Worker: public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = 0): QObject(parent);
signals:
void resultReady(BigData *data);
public slots:
void doWork() {
BigData *data = new BigData(this); // alloc new Data
while (!dataReady) {
... // appending data
}
// Data ready
// clearing ownership
data->setParent(NULL); // data can't be moved to another thread with parent
data->moveToThread(NULL);
emit resultReady(data);
}
};
void MainWindow::handleResult(BigData *data)
{
if (currentData_) {
delete currentData_;
}
data->setParent(this); // set new ownership
// works only if data's thread is NULL
data->moveToThread(QApplication::instance()->thread());
currentData_ = data;
}
好看吗?或者有更合适的方法吗?
最佳答案
通常您使用 moveToThread()
将一个对象从一个线程推送到另一个线程。这意味着不是在 doWork() 中执行
槽,你可以写 data->moveToThread(NULL);
data->moveToThread(QApplication::instance()->thread());
来避免将线程关联设置为 NULL
和然后从主线程更改它。但是在将 BigData
实例移动到主线程后,请注意从工作线程中触摸 QObject
。另一件需要注意的事情是,在线程之间来回移动 QObject
可能会导致一些副作用,来自 docs :
Note that all active timers for the object will be reset. The timers are first stopped in the current thread and restarted (with the same interval) in the targetThread. As a result, constantly moving an object between threads can postpone timer events indefinitely.
仅仅为了内存管理的目的而继承QObject
是矫枉过正。 QObject
提供 much more stuff (内省(introspection)功能、动态属性、信号/槽、线程亲和性、事件处理、国际化......)你在这里并不真正需要。
如果您只对内存管理感兴趣,Qt和 the C++ standard library具有可以通过唯一所有权或共享所有权语义实现对象生命周期管理的智能指针。
看看this answer有关将数据加载卸载到全局线程池并在准备就绪后立即在 View 中显示这些数据的模型示例。注意模型继承了QObject
(因为QAbstractItemModel
继承了QObject
,因为它使用signals/slots来通知 View 数据变化)但是数据没有原因实际保存数据的结构继承QObject
。 . .
关于c++ - QThread 将结果数据传递给 MainThread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43150691/