4

此 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;

这基本上是一种显示网页内容的“同步”方式。

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

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

有可能发生这种情况,还是我不了解 Qt 事件循环的工作原理?

4

2 回答 2

1

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

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

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

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

于 2012-05-13T08:17:30.720 回答
-1

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

于 2012-05-13T13:25:24.807 回答