Qt线程在调用exit/quit后不停止 [英] Qt thread does not stop after calling exit/quit

查看:149
本文介绍了Qt线程在调用exit/quit后不停止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图更好地理解 Qt 信号和插槽以及线程.所以我尝试了这个最小的应用程序:

I'm trying to find a better understanding of Qt signals and slots in conjunction with threads. So I tried this minimal application:

foo.h:

#include <QObject>

class A : public QObject {
  Q_OBJECT

public:
  void doit();

signals:
  void x();
};

class B : public QObject {
  Q_OBJECT

public slots:
  void h();
};

foo.cpp:

#include "foo.h"

#include <QThread>
#include <QCoreApplication>

void B::h() {
  qDebug("[%d] B::h() here!", (int) QThread::currentThreadId());
  QCoreApplication::instance()->quit();
}

void A::doit() {
  qDebug("[%d] emitting...", (int) QThread::currentThreadId());
  emit x();
}

int main(int argc, char* argv[]) {
  QCoreApplication app(argc, argv);
  A a;
  B b;
  QObject::connect(&a, SIGNAL(x()), &b, SLOT(h()));
  QThread t;
  t.start();
  b.moveToThread(&t);
  a.doit();
  t.wait();
  return 0;
}

一切都很好,只有最后的 t.wait() 永远不会返回.我的理解是调用 quit() 应该停止事件循环,这意味着 exec() 应该返回,所以 run() 和线程执行应该停止.我错过了什么吗?

Everything is fine, only the t.wait() at the end never returns. My understanding is calling quit() should stop the event loop, which means exec() should return and so should run() and thread execution should stop. Am I missing something?

推荐答案

QCoreApplication::quit () 未声明为线程安全方法,因此您不能从另一个线程调用它.您的应用程序可能会崩溃或出现未定义的行为 (UB).

QCoreApplication::quit () is not stated as thread-safe method so you can't call it from another thread. Your application can crash or get an undefined behavior(UB).

t.wait() 永远不会返回,因为正在运行的线程一直在等待事件.要停止线程,您必须调用 QThread::quit () [slot]

t.wait() will never return because the running thread is constantly waiting for events. To stop the thread you must call QThread::quit () [slot]

如果你想在工作完成后退出应用程序,你必须发出一个信号,该信号连接到QCoreApplication::quit() [static slot]

If you want to quit the application after the work is done you have to emit a signal, which is connected to QCoreApplication::quit () [static slot]

如果你想在工作完成后停止工作线程你还必须发出一个信号,连接到void QThread::quit() [slot]

If you want to stop the worker thread after the work is done you also have to emit a signal, connected to void QThread::quit () [slot]

添加:线程、事件和 QObjects 以供进一步阅读

Added: Threads, Events and QObjects for further reading

重要通知:您必须调用 QCoreApplication::exec() 才能使用信号 &线程之间的槽机制,排队连接.

Important notice: You must call QCoreApplication::exec() in order to be able to use signal & slot mechanism between threads, queued connections.

来自 Qt QThread 文档:

From Qt QThread doc:

每个 QThread 可以有自己的事件循环.您可以启动事件循环通过调用 exec();您可以通过调用 exit() 或 quit() 来停止它.拥有线程中的事件循环可以连接来自其他线程插入此线程中,使用一种称为 排队的机制联系.它还可以使用需要线程中的事件循环,例如 QTimer 和 QTcpSocket.笔记,但是,不可能在线程.

Each QThread can have its own event loop. You can start the event loop by calling exec(); you can stop it by calling exit() or quit(). Having an event loop in a thread makes it possible to connect signals from other threads to slots in this thread, using a mechanism called queued connections. It also makes it possible to use classes that require the event loop, such as QTimer and QTcpSocket, in the thread. Note, however, that it is not possible to use any widget classes in the thread.

Qt::QueuedConnection 文档:

Doc for Qt::QueuedConnection:

当控制返回到接收者线程的事件循环.该插槽在接收者的线程.

The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread.

这篇关于Qt线程在调用exit/quit后不停止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆