在取消线程上使用 QFuture 释放内存

Posted

技术标签:

【中文标题】在取消线程上使用 QFuture 释放内存【英文标题】:Free memory using QFuture on cancel thread 【发布时间】:2018-07-11 11:01:23 【问题描述】:

我正在编写一个使用QtConcurrent 启动线程的程序。就我而言,当我使用鼠标滚动时,我使用它来呈现 QGraphicsView。

我正在使用以下代码启动线程:

if (future.isRunning()) 
    future.cancel();


future = QtConcurrent::run(this,&AeVectorLayer::render, renderparams, pos);
watcher.setFuture(future);

当线程完成时,我用QfutureWatcher 捕获信号finished

这是我的渲染函数:

QList<AeGraphicsItem*> AeVectorLayer::render(Ae::renderParams renderparams, int pos)

    AeVectorHandler *coso = new AeVectorHandler();
    coso->openDataset(AeLayer::absoluteFilePath);
    coso->setTransformCoordinates(myEPSG);
    QList<AeGraphicsItem*> bla = coso->getItems(renderparams.sceneRect.x(), 
    renderparams.sceneRect.y(), renderparams.sceneRect.width(), 
    renderparams.sceneRect.height(), renderparams.zoom, color, this);
    for (int i = 0; i < bla.size(); i++)
        bla.at(i)->setZValue((qreal)pos);
    delete coso;
    return bla;

如您所见,我的渲染函数中有一个QList&lt;QGraphicsItem*&gt;。当未来被取消时,我怎样才能销毁这个列表?我不明白在我的代码中我正在重新定义 future 变量,但我不知道如何避免它。

【问题讨论】:

根据documentationQFuture返回的QtConcurrent::run可以被取消。 @G.M.是的,我知道这一点。但是当您使用 cancel() 方法时,您可以在线程完成时从 QFutureWatcher 接收 Canceled() 事件。我的问题是我丢失了对已取消线程的引用,我无法接收此事件。在这种情况下,我可以删除 QList 并避免内存问题。 您需要提供更多信息。谁或什么负责bla 中的AeGraphicsItem * 项目的所有权?还有,为什么coso分配在free store而不是stack上? @G.M. coso 分配在免费商店,因为仅用于使用 OGR 打开 shapefile (*.shp) 并将我的几何列表转换为 QGraphicsItem 【参考方案1】:

停止尝试手动管理内存,而是使用适合您用例的智能指针。因为您使用不知道移动的QFuture,所以您需要一个std::shared_ptr。一旦QFuture/QFutureWatchers 超出范围,并且您不再持有shared_ptr 实例,该资源将被删除。所以在你的情况下,你的render 函数应该返回一个QList&lt;std::shared_ptr&lt;AeGraphicsItem&gt;&gt;。当您将所有权从shared_ptrs 转移到例如QGraphicsScene:所有权转让时,您必须从shared_ptrrelease

请注意,您的isRunning 检查后跟cancel 存在根本缺陷:未来可能在您调用isRunning 时运行,但在您调用cancel 时完成。如果您想取消它,只需致电cancel。另请注意,您无法有意义地取消 QtConcurrent::run 返回的 QFutures,因此您所做的事情本身就是非常非常错误的。

【讨论】:

我尝试使用它,但无法很好地运行该程序。我决定使用一个继承自 QThread 的类并实现我自己的 Cancel() 方法。感谢您的帮助。

以上是关于在取消线程上使用 QFuture 释放内存的主要内容,如果未能解决你的问题,请参考以下文章

为啥用C#在磁盘上写入文件后内存没有释放

SylixOS 线程取消处理流程

Python多线程 - 使用While语句运行时未释放内存

释放共享内存段

对等体断开连接后未释放SSL内存

C#线程不释放内存