c++ - QThread 将结果数据传递给 MainThread

标签 c++ multithreading qt qthread

我正在考虑如何将结果数据从某个工作线程传回客户端而不进行复制。 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)功能、动态属性、信号/槽、线程亲和性、事件处理、国际化......)你在这里并不真正需要。

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

看看this answer有关将数据加载卸载到全局线程池并在准备就绪后立即在 View 中显示这些数据的模型示例。注意模型继承了QObject(因为QAbstractItemModel继承了QObject,因为它使用signals/slots来通知 View 数据变化)但是数据没有原因实际保存数据的结构继承QObject。 . .

关于c++ - QThread 将结果数据传递给 MainThread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43150691/

相关文章:

c++ - 优化 2D 旋转

c++ - 从类中的对象调用类中函数的最佳方法

c++ - QtCreator : Target debug/. ..obj 不存在

c++ - 读入数字但止于负 C++

c++ - 用 bool 类型包装返回值

c++ - 段错误,使用 pthread_exit() 终止线程

android - IntentService 和线程池

c# - 具有基于任务的异步模式的 UDP 监听器

c++ - QApplication::processEvents 在 Windows 中不工作

c++ - Qt 5 和 LibVLC