我正在考虑如何将结果数据从某些工作线程传递回客户端而不进行复制。 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() 将对象从一个线程推到另一个线程。 这意味着您无需编写data->moveToThread(NULL);插槽中的doWork(),而是可以编写data->moveToThread(QApplication::instance()->thread());来避免将线程亲和性设置为NULL,然后从主线程进行更改。但是,在将BigData实例移动到主线程之后,请注意,需要从工作线程中触摸该QObject。要注意的另一件事是,在线程之间来回移动QObject可能会导致docs产生一些副作用:



仅出于内存管理目的而继承的QObject是一种过大的QObject提供了您实际上不需要的much more stuff(自省(introspection)功能,动态属性,信号/插槽,线程亲和力,事件处理,国际化...)。

如果只对内存管理感兴趣,Qtthe C++ standard library具有智能指针,可以通过唯一所有权或共享所有权语义实现对象生存期管理。

请查看this answer的模型示例,该模型可将数据加载卸载到全局线程池中,并在数据就绪后立即在 View 中显示这些数据。请注意,该模型继承了QObject(因为 QAbstractItemModel 继承了QObject,因为它使用信号/插槽通知数据更改的 View ),但是实际上保留数据的数据结构没有理由继承QObject。 。 。

10-06 13:05
查看更多