这段代码可能会陷入无限循环吗?

Could this code potentially run into an infinite loop?

本文关键字:无限循环 段代码 代码      更新时间:2023-10-16

这个Qt代码是否有可能陷入无限循环?

QNetworkAccessManager m;
QNetworkReply *reply = m.get(QNetworkRequest(QUrl("http://www.example.org/")));
QEventLoop loop;
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
qDebug() << reply->readAll();
delete reply;

这基本上是显示网页内容的"同步"方式。

我没有观察到使用它的任何问题,但我考虑了以下情况:

  • replyfinished信号在创建事件环路之前发出,并在finishedquit之间建立信号槽连接
  • 从该点开始不会发出任何信号,因此永远不会触发quit
  • loop.exec()将不断循环

是否有可能发生这种情况,或者我对Qt事件循环的工作原理有所了解?

虽然Qt执行你自己的代码(例如上面的代码),但它不能处理新信号和调用时隙。在执行方法时发出的每个信号都将在以后进行处理。如果要在方法中间强制处理信号,可以调用QCoreApplication::p rocessEvents来处理当前事件循环中的信号,或调用QEventLoop::exec在另一个循环中处理信号。

所以这个代码是安全的。如果信号来得太快,它将在事件队列中等待。

如果您正在发射信号,并且有插槽使用 Qt::D irectConnection 连接到该信号,则这些插槽将立即执行。但这与您的情况不符。Qt必须在发出单曲之前执行一些内部代码。它无法在执行方法时执行此代码。只有一个线程和一个调用堆栈。

请注意,当您使用Qt线程时,事件循环的行为更加复杂。

在运行loop.exec()之前,你可以检查reply->isFinished()。如果是,请不要执行循环。