QtのQNetwork *クラスで「同期的な」コールを行うアプリがあります。さまざまなソースからオンラインで適応されたコードは、次のようになります。Qtネットワークリクエストの条件変数
QNetworkRequest request("http://www.somedomain.com");
QNetworkReply* pReply = _manager->get(request);
// A not-so-great-solution to wait for the request, but works
QEventLoop loop;
QObject::connect(pReply, SIGNAL(finished()), &loop, SLOT(quit()), Qt::DirectConnection);
loop.exec(QEventLoop::ExcludeUserInputEvents);
// Now the pReply object has what I want, yay!
これはハックであることを認識して実装しました。代わりにC++の条件変数を使って同様のことを達成できるかどうか疑問に思った。これは、条件変数を試して初めてですので、私はこれで私は条件変数であることはもちろん_requestCV
で正しく(それらを使用しています完全にはよく分からない
QNetworkRequest request("http://www.somedomain.com");
QNetworkReply* pReply = _manager->get(request);
QObject::connect(pReply, &QNetworkReply::finished,
[this]()
{
std::unique_lock<std::mutex> lock(_requestMutex);
_requestCV.notify_one();
});
std::unique_lock<std::mutex> lock(_requestMutex);
_requestCV.wait(lock, [this, pReply]()
{
return pReply->isFinished();
});
:これを試みる私のコードは次のようになります例)。しかし、本当に私が困惑しているのは、QNetworkReply :: finished lambdaは決して実行されないということです。最初の例では、finished()イベントがすぐに起動しているように見えます.QNetworkReplyには、私が期待していたすべてがあります。 2番目の例でpReplyのfinished()イベントが呼び出されないのはなぜですか?
注:同期ネットワークコール、特に非同期で使用するように設計されたQtのモデルについては、多くの人が強く感じていることを理解しています。しかし、それは私がこの質問で議論することに興味があるわけではありません。ありがとうございました。
現在のスレッドでのみブロックしていませんか?このコード自体が別のスレッドで実行されると、イベントループはまだブロックされますか? – Addy
@Addy QNetworkAccessManager :: get()を呼び出すと同じスレッドをブロックするように見えるので、スレッドをブロックするか、別のスレッドからgetを呼び出す(スレッドセーフではないと思います...) 。 – hyde
@Addy「このコード自体が別のスレッド上で実行されても、イベントループはブロックされますか?」*各スレッドにはイベントループがありますが、それがポイントです:シグナルを送信するループをブロックしています。 – Ilya