这个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
的{{1}}信号,finished
和quit
之间的信号槽连接是由quit
loop.exec()
会不断循环是否有可能发生这种情况,或者我不了解Qt事件循环的工作原理?
答案 0 :(得分:1)
当Qt执行您自己的代码(例如上面的代码)时,它无法处理新信号和调用插槽。执行方法时发出的每个信号都将在稍后处理。如果要在方法中间强制处理信号,可以调用QCoreApplication::processEvents来处理当前事件循环中的信号,或QEventLoop::exec在另一个循环中执行此操作。
所以这段代码是安全的。如果信号过快,它将在事件队列中等待。
如果您正在发出信号并且使用Qt::DirectConnection将信号连接到此信号,则这些插槽将立即执行。但这与你的情况不符。 Qt必须在发出信号之前执行一些内部代码。在执行方法时,它无法执行此代码。只有一个线程,只有一个调用堆栈。
请注意,当您使用Qt线程时,事件循环的行为会更复杂。
答案 1 :(得分:-1)
在运行loop.exec()
之前,您可以检查reply->isFinished()
。如果是,就不要执行循环。