QThread 将结果数据传递给 MainThread

QThread pass result data to MainThread

我正在考虑如何将结果数据从某个工作线程传回客户端而不进行复制。 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() to push an object from one thread to another. This means that instead of doing data->moveToThread(NULL); in your doWork() slot, You can write data->moveToThread(QApplication::instance()->thread()); to avoid setting the thread affinity to NULL and then changing that from the main thread. But after moving the BigData instance to the main thread, Be aware of touching that QObject from the worker thread. Another thing to note about is that, moving a QObject back and forth between threads might cause some side effects, from the 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(内省功能、动态属性、signals/slots、线程亲和性、事件处理、国际化......),你在这里并不真正需要。

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

看看 for an example of a model that offloads data loading to the global thread pool and displays these data in the view as soon as they are ready. Notice that the model inherits QObject (because QAbstractItemModel继承QObject,因为它使用signals/slots来通知视图数据变化)但是没有理由实际保存数据的数据结构继承QObject。 . .