QThread 正在造成内存泄漏

2024-03-23

经过对我的 QT 应用程序进行大量测试和更改后,Visual Leak Detector 识别出了令人讨厌的泄漏源(8 字节)。 VLD 报告 QT 应用程序是干净的,除了QThread*指针。

一些实现背景:该应用程序由 Jeffrey Holmes 建模为解决方案的混合体,使用Qt批量下载网页 https://stackoverflow.com/questions/3910105/bulk-download-of-web-pages-using-qt。感谢 Jeffrey 提供的早期解决方案!

问题:

  • Why is QThread*当工作线程完成其工作时不会销毁自身?

  • 我怎样才能强制QThread*工作完成后删除线程和工作对象?

  • Should QThread以不同的方式实施?

Code:

void vqMDIChildDialog::processWorkQueue(bool bIsBC)
{

if (m_listOfTables.isEmpty() && currentReplicationThreads == 0)
{
}
else if (!m_listOfTables.isEmpty())
{
    for (int i = 0; i < maxReplicationThreads && !m_listOfTables.isEmpty();i++)
    {
        QThread *thread = new QThread;
        QPointer<vcSharedDataQt> worker = new vcSharedDataQt();
        worker->moveToThread(thread);
        QString tmpTableName (m_listOfTables.dequeue());
        worker->setParentObject(this);
        //   
        // set properties on the worker object.
        //  
        connect(thread,  SIGNAL(started()),  worker, SLOT(process()));
        connect(worker,  SIGNAL(finished()), thread, SLOT(quit()));
        connect(worker,  SIGNAL(finished()), worker, SLOT(deleteLater()));
        connect(thread,  SIGNAL(finished()), thread,SLOT(deleteLater()));

        connect(worker,
            SIGNAL(updateMessageFromThread(  const QString&,
                             const QString&,
                             const QString&,
                             const QString&,
                             const QString&,
                             const QString&,
                             const QString&)), 

            this,
            SLOT(UpdateStatusBarFromThread( const QString&,
                            const QString&,
                            const QString&,
                            const QString&,
                            const QString&,
                            const QString&,
                            const QString&)));

        thread->setObjectName(worker->getUniqueKey());

        thread->start();
        currentReplicationThreads ++;
    }
}

}

Stack 不允许我回答这个问题,所以:

该功能受到保护QMutex:

mutex.lock();
processWorkQueue();
mutex.unlock();

这导致了内存泄漏。QThread显然无法在工作线程完成时销毁。我删除了互斥锁,VLD 报告没有内存泄漏QThread.


  1. A QThread并不真正知道它的工作何时完成。您可以通过思考如何实现这一点来回答您自己的问题。

    Its run()方法只是旋转一个事件循环。由于事件循环可以知道是否有任何事件发布到它,因此您可以合理实现的唯一条件是在没有进一步的事件时退出线程。这会使线程立即退出,所以它根本没有帮助。

    也许您希望在没有更多线程时终止线程QObject以线程作为线程的 s。这当然可以作为可选行为来实现QThread,但我不知道这个改变是否会被接受。它不能是一种默认行为,因为在许多情况下,不断地销毁和重新创建线程根本就是一种浪费——人们可能希望保留一个没有对象的线程。

    最终只有您知道线程的工作何时完成。您的工作对象可以调用thead()->quit()或者它可以在完成时发出信号 - 就像您已经做的那样。

  2. A QThread工作完成后不能自行销毁,因为线程是可重新启动的。您可以完全控制线程的生命周期,因此你当然可以当它的工作完成时就摧毁它,你已经这样做了,只是你做错了。

  3. 你的问题实际上是按照你希望事情发生的顺序排列的。这deleteLater操作由事件循环执行。如果线程的事件循环没有运行,deleteLater是一个NO-OP。

    因此,首先,您的连接应该形成一个只能以明确定义的顺序执行的级联:

    connect(thread, SIGNAL(started()),  worker, SLOT(process()));
    connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
    connect(worker, SIGNAL(destroyed()), thread, SLOT(quit()));
    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    

    然后,您必须确保您所在的线程processWorkQueue方法运行不会被阻止并且有机会its事件循环继续进行。正是这个事件循环将处理线程的删除。

    正如 AlexP 所指出的,这在 Qt 4.7 或更早版本中不起作用,因为所有这些版本在 QThread 的实现中都有一个错误。 “QThread 的行为已经改变”是“有一个丑陋的错误最终被修复”的委婉说法。

  4. 您的连接过于冗长。您可以从签名中删除空格和引用/常量引用。第三个参数也是可选的,如果它是this。它应该看起来像:

    connect(worker,                                    
            SIGNAL(updateMessageFromThread(QString,QString,QString,QString,
                                           QString,QString,QString)),
            SLOT(updateStatusBarFromThread(QString,QString,QString,QString,
                                           QString,QString,QString)));
    
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QThread 正在造成内存泄漏 的相关文章

  • 从布局中按名称获取小部件

    如果我想从 python Qt 的布局中获取特定的小部件 我应该如何进行 到目前为止我所做的 for i in range self ui horizontalLayout 14 count here it does fail name s
  • Java:为什么它使用固定数量的内存?或者它如何管理内存?

    JVM 似乎使用了一些固定数量的内存 至少我经常看到参数 Xmx 对于最大尺寸 和 Xms 对于初始大小 这表明 我感觉 Java 应用程序不能很好地处理内存 我注意到一些事情 即使一些非常小的示例演示应用程序也会加载大量内存 也许这是因为
  • CPU Relax 指令和 C++11 原语

    我注意到许多使用特定于操作系统的原语实现的无锁算法 例如所描述的自旋锁here http locklessinc com articles locks 使用 Linux 特定的原子原语 经常使用 cpurelax 指令 使用 GCC 可以通
  • 我对线程失去了理智

    我想要这个类的对象 public class Chromosome implements Runnable Comparable
  • 64 位大型 malloc

    malloc 失败的原因是什么 尤其是在 64 位中 我的具体问题是尝试在 64 位系统上分配一大块 10GB RAM 该机器有 12GB RAM 和 32GB 交换空间 是的 malloc 是极端的 但是为什么它会成为一个问题呢 这是在带
  • Qt 文件对话框默认后缀不起作用

    我将以下代码用于 QtQuick Dialogs 1 3 和 Qt 5 10 0 下 filedialog 的新属性 我使用 Qt Creator 5 10 默认套件构建它 import QtQuick 2 10 import QtQuic
  • C#中为线程指定特殊的cpu

    我有 2 个线程 我想告诉其中一个在第一个 cpu 上运行 第二个在第二个 cpu 上运行 例如在具有两个 cpu 的机器中 我怎样才能做到这一点 这是我的代码 UCI UCIMain new UCI Thread UCIThread ne
  • 在 Three.js 中从 Web Worker 加载纹理

    当将大纹理图像应用到网格上一段明显的时间时 Three js 会锁定浏览器的主线程 让我们考虑以下示例 var texLoader new THREE TextureLoader texLoader load someLargeTextur
  • 理解 JavaScript 的单线程本质

    我一直在阅读 John Resig 的 JavaScript Ninja 的秘密 它解释了 JavaScript 是单线程的 但是 我尝试对此进行测试 但我不确定要从这里删除什么 executing this in browser func
  • 使用 boost::thread 特定的 ptr<>::get() 是否会很慢?有什么解决方法吗?

    我目前正在使用 Valgrind 的 Callgrind 分析一个存在性能问题的应用程序 在查看分析数据时 似乎有 25 的处理时间花费在boost detail get tss data在主要目的是物理模拟和可视化的应用程序中 get t
  • 如何获取 QTableView 的标题列表?

    我有一个QTableView我的对话框中的对象 我需要访问该表的水平标题并将它们放入QStringList object 尽管进行了大量搜索 但我在 Qt 文档中找不到如何获取此标头列表 编辑 我发现的最接近的地方是this https w
  • 新任务中使用的依赖注入服务

    我在需要时使用依赖项注入来访问我的服务 但我现在想要创建一个并发任务 但这会由于依赖项注入对象及其生命周期而导致问题 我读过这篇文章 标题 防止多线程 Link http mehdi me ambient dbcontext in ef6
  • QFileDialog::getSaveFileName 和默认的 selectedFilter

    我有 getSaveFileName 和一些过滤器 我希望当用户打开 保存 对话框时选择其中之一 Qt 文档说明如下 可以通过将 selectedFilter 设置为所需的值来选择默认过滤器 我尝试以下变体 QString selFilte
  • 如何使QTableView类的restoreState()和saveState()正常工作?

    首先 我想说 我的问题已经在这里讨论过 并且这里是 https stackoverflow com questions 1163030 qt qtableview and horizontalheader restorestate 但答案并
  • 如何停止提交给 ExecutorService 的 Callable?

    我正在尝试实现一个示例应用程序来测试Callable and ExecutorService接口 在我的应用程序中我已经声明 ExecutorService exSvc Executors newSingleThreadExecutor T
  • 调试 Java InterruptedException,即查找原因

    在调试Android应用程序时 有时中断异常发生并使应用程序崩溃 我已经能够在默认异常处理程序上设置断点 但调用堆栈不提供信息 at java util concurrent locks AbstractQueuedSynchronizer
  • Qt:测量事件处理时间

    我想测量我的应用程序中的哪些事件在主线程中需要很长时间才能执行 阻塞 GUI 或者至少是否有任何事件花费的时间超过 比如说 10 毫秒 显然 我对需要很长时间的任务使用线程和并发 但有时很难在其他线程中放入的内容和可以保留在 GUI 中的内
  • 从 Invoke 方法获取 RETURN

    我正在尝试从另一个线程上的列表框项目中读取值 我尝试创建一种新方法来运行调用命令 我可以设法将命令发送到列表框 例如通过调用方法添加 但我似乎无法得到响应 我似乎无法获取该项目的值 我尝试了几种方法 一旦我将它从空变为字符串 事情就开始变得
  • 在 MacOS 终端上运行 ffmpeg [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我对 MacOS 相当陌生 我发现使用终端来获取信息并不容易ffmpeg和我在 Window 上一样正常运行 我有 ffmpeg 二进制文件ffmpe
  • PyQt5:如何使QThread返回数据到主线程

    I am a PyQt 5 4 1 1初学者 我的Python是3 4 3 这是我尝试遵循的many https mayaposch wordpress com 2011 11 01 how to really truly use qthr

随机推荐

  • 使用 grep 列出目录中的条目

    我试图列出目录中名称仅包含大写字母的所有条目 目录需要附加 bin bash cd testfiles ls grep r 由于 grep 默认情况下仅查找大写字母 对吗 因此我只是在 testfiles 下的目录中递归搜索仅包含大写字母的
  • 将 nlog 中的记录添加到 dataType = date 的字段

    I use nlogdll 写入数据库 Oracle 与实体框架在行中 logger Log logLevel try 我在 nlog 日志中收到以下错误 文字与模板字符串不匹配 代码是 SetPropGDC LogEntity NLog
  • 在 Windows 上使用 Xerces 3.0.1 和 C++ 编写 XML

    我编写了以下函数来使用 Xerces 3 0 1 创建 XML 文件 如果我使用 foo xml 或 foo xml 的文件路径调用此函数 它会很好用 但如果我传入 c foo xml 然后我在这一行得到一个异常 XMLFormatTarg
  • C#通过OLEDB从Excel中提取格式化文本

    我正在从一个大的数据中读取数据excel已格式化文本的文件 我将数据提取到DataTable对象通过oleDBConnection GetOleDbSchemaTable 但提取的数据不包含任何格式化信息 我的要求是 我只需要提取非删除线文
  • 如何使用 Android Gradle 插件 0.7 配置 NDK

    新的 Android gradle 插件 0 7 似乎包含了对 NDK 的新支持 但在文档中几乎没有提到它 我找到的唯一参考是一个名为ndkSanAngeles https android googlesource com platform
  • 优化 Excel 公式 - SUMPRODUCT 与 SUMIFS/COUNTIFS

    根据一些网站的说法 SUMIFS 和 COUNTIFS 比 SUMPRODUCT 更快 例如 http exceluser com blog 483 excels sumifs or sumproduct which is faster h
  • 用于提供静态内容的 Servlet

    我在两个不同的容器 Tomcat 和 Jetty 上部署了一个 web 应用程序 但它们用于提供静态内容的默认 servlet 有不同的方式来处理我想要使用的 URL 结构 details http issues apache org bu
  • 除主活动外,其他活动中没有应用栏和抽屉

    主要活动 public class MainActivity extends AppCompatActivity Override protected void onCreate Bundle savedInstanceState supe
  • 何时使用 Dart 中的接口?

    我正在阅读 Dart 的文档 对于如何使用接口 我有点困惑 也许是因为我来自 Ruby 当然 接口并不是 Dart 所独有的 关于何时应该使用接口有很多解释 This one https stackoverflow com question
  • Web 开发 - 对象数据库与关系数据库

    使用对象数据库或关系数据库进行涉及大量 CRUD 的常规 Web 开发有何优缺点 更新 我重新打开了赏金奖励 以便给内维尔 OODBMS 的概念已经被打破 过去几十年中出现的各种商业和免费产品几乎没有在市场上产生影响 就您可以向数据提出的问
  • 无法从 Play 商店生产区域停用 Android 分阶段推出应用程序

    我们将一款 Android 应用上传到 Play 商店 分阶段向 5 的市场推出 不确定谷歌在这里如何定义市场 但这是另一个问题 我们决定删除该应用程序并恢复之前发布的应用程序 然而 这似乎是不可能做到的 当我在开发人员控制台上切换到高级模
  • SQL Server 是否优化 LIKE ('%%') 查询?

    我有一个存储过程 它对记录执行搜索 问题是一些来自 UI 的搜索条件可能是空字符串 因此 当未指定条件时 LIKE 语句就变得多余 如何有效地执行该搜索或 Sql Server 或者 它是否优化 LIKE 查询 因为这意味着没有什么可比较的
  • 数据点更改后插入行

    我有一个数据集 如下所示 This1 GH This2 GH This3 GH This4 BR This5 BR This6 VB 当数据点发生变化时 即 GH 变为 BR 时 我希望 Excel 插入换行符 所以最终的数据看起来像这样
  • 在下载管理器中,如何在通知栏“取消”时获取状态?

    我正在使用下载管理器在 Android 中下载文件 但是 当点击通知栏上的 取消 按钮时 我无法收到任何广播 我只找到两个广播 1 DownloadManager ACTION DOWNLOAD COMPLETE 2 DownloadMan
  • 使用 Bootstrap 2 将某些地方的字形颜色更改为蓝色,但不是全部地方

    我的 UI 使用 Bootstrap 框架 我想将字形的颜色更改为蓝色 但不是在所有地方 在某些地方它应该使用默认颜色 我已经参考了这两个链接 但没有发现任何有用的信息 我可以仅使用 CSS 为 bootstrap 图标添加颜色吗 http
  • 动态更改母版页中的菜单类别

    我如何更改母版页中菜单的 CSS 类名称 子页面 当菜单的任何子形式打开时 我想将类更改为 活动 有可用的 C 或 JavaScript 代码吗 Thanks 通过理解你的问题 我认为你想在页面更改时更改 li 的类或菜单中使用的任何标签
  • Ms Access 是 DBMS 还是 RDBMS?

    Ms Access 是 DBMS 还是 RDBMS 我也在谷歌上找到这个问题的答案 但在一些网站或博客中说它是DBMS 而另一些则说它是RDBMS 那么正确答案是什么 请理解为什么是 DBMS 或 RDBMS 简答 Both Detail
  • 在嵌套的 If 中应用两个条件或与 And 一起使用单个条件哪个更好? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 嵌套 If 或单个 if 与 And 运算符 哪个是更好的方法 单个 If 与 And if txtPackage Text string Em
  • GWT 程序是否有办法判断它是处于托管模式还是 Web 模式?

    我希望我的 GWT 程序能够确定它是处于托管模式还是 Web 模式 有没有办法做到这一点 Thanks GWT isScript 在非托管模式下返回 true 在托管模式下返回 false http google web toolkit g
  • QThread 正在造成内存泄漏

    经过对我的 QT 应用程序进行大量测试和更改后 Visual Leak Detector 识别出了令人讨厌的泄漏源 8 字节 VLD 报告 QT 应用程序是干净的 除了QThread 指针 一些实现背景 该应用程序由 Jeffrey Hol