【问题标题】:Properly delete QThread正确删除 QThread
【发布时间】:2015-07-15 22:05:55
【问题描述】:

我是 QT 新手,我正在尝试在按钮单击时创建和销毁 QThread(可能多次)。我已经阅读了很多帖子,但我的线程要么没有被破坏,要么在 QMain.dll 中导致无法追踪的堆异常。

我这样创建我的线程:

thread = new QThread;
reader = new Reader(); //a QObject subclass
reader->moveToThread(thread);
connect(thread, SIGNAL(started()), reader, SLOT(read()));
connect(reader, SIGNAL(timeout()), this, SLOT(threadTimeout()));

connect(reader, SIGNAL(finished()), reader, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), this, SLOT(threadFinished()));

线程然后循环运行并发送数据。 read() 函数如下所示:

void Reader::read() { 
  while(!stop) {
    //... do something ...
  }
  emit finished();
}

On Button click I call

reader->setStop(true);

这打破了线程的while循环。发出完成的信号,但随后触发内存异常。如果我删除两个 deleteLater() 插槽,则不会引发异常,但线程(显然)没有被删除。

我在这里做错了吗?提前致谢。

【问题讨论】:

  • 查看 Qt 文档中的 QThread。工作人员未连接到deleteLater,并且工作人员resultReady,我认为它与您的Reader::finished 相同,连接到插槽handleResults,我认为与您的threadFinished 相同.看看那里并做出相应的调整。
  • 我试过了,但这并没有删除我的线程。在这个例子中 thread->quit() 和 thread->wait() 在主类的析构函数中被调用。我不能这样做,因为我想在不调用主类的析构函数的情况下多次打开和关闭线程。

标签: c++ multithreading qt


【解决方案1】:

主要问题是您正在删除线程对象(即 QThread),而 执行线程 正在运行。在你的threadFinished(),这实际上是任务完成,你需要做:

 thread->quit();
 thread->wait();
 thread->deleteLater();
 reader->deleteLater();

并删除finished -> deleteLater 连接。

【讨论】:

  • 感谢您的回复。我试过了,但现在执行卡在 thread->wait();有什么想法吗?
  • 如果我省略了线程->wait(),我会再次得到内存异常。
  • 该线程中仍有一个对象正在执行。 reader 是唯一的吗?你能确定read() 终止吗?好像没有
  • 我认为错误出在其他地方。如果我从 while 循环中删除所有代码,则您提出的方法效果很好。谢谢
【解决方案2】:

尝试为leaving thread 事件循环添加这样的连接。

connect(reader, SIGNAL(finished()), thread, SLOT(quit()));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-11
    • 2017-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-20
    • 1970-01-01
    相关资源
    最近更新 更多