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;

これは基本的に、Webページのコンテンツを表示するための「同期」方法です。

私はそれを使用して問題を観察していませんが、私は次のシナリオを検討しました:

  • finished信号は、イベントループが作成され、との間の信号スロット接続が確立さreplyれるに発行されます。finishedquit
  • そのポイントから前方に信号が発信されないため、トリガーされることはありませんquit
  • loop.exec()継続的にループします

それが発生する可能性はありますか、それともQtイベントループがどのように機能するかについて何か理解していませんか?

4

2 に答える 2

1

Qtは独自のコード(たとえば、上記のコード)を実行しますが、新しいシグナルやコールスロットを処理することはできません。メソッドの実行中に発行されたすべてのシグナルは、後で処理されます。メソッドの途中でシグナルの処理を強制する場合は、QCoreApplication :: processEventsを呼び出して現在のイベントループでシグナルを処理するか、QEventLoop::execを呼び出して別のループで処理することができます。

したがって、このコードは安全です。信号の到着が速すぎると、イベントキューで待機します。

シグナルを発信していて、 Qt :: DirectConnectionを使用してこのシグナルに接続されているスロットがある場合、これらのスロットはすぐに実行されます。しかし、これはあなたの場合とは一致しません。信号が出力される前に、Qtはいくつかの内部コードを実行する必要があります。メソッドの実行中は、このコードを実行できません。スレッドは1つだけで、呼び出しスタックは1つだけです。

Qtスレッドを使用している場合、イベントループの動作はより複雑になることに注意してください。

于 2012-05-13T08:17:30.720 に答える
-1

実行する直前にloop.exec()、を確認できreply->isFinished()ます。そうである場合は、ループを実行しないでください。

于 2012-05-13T13:25:24.807 に答える