【发布时间】:2016-03-20 21:30:01
【问题描述】:
我有一个应用程序,我在其中使用 Qt 的 QNetwork* 类进行一些“类似同步”的调用。从网上各种来源改编的代码如下:
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!
我知道这是一个 hack,所以我实现了这个。我开始想知道是否可以改用 C++ 的条件变量来实现类似的效果。我尝试这样做的代码如下所示:
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();
});
这是我第一次尝试条件变量,所以我不完全确定我是否正确使用它们(_requestCV 当然是本例中的条件变量)。但真正让我困惑的是 QNetworkReply::finished lambda 永远不会执行。在第一个示例中,finished() 事件似乎几乎立即触发,并且 QNetworkReply 具有我所期望的一切。为什么在第二个示例中从未调用 pReply 的 finished() 事件?
注意:我知道很多人对同步网络调用有强烈的感觉,尤其是 Qt 的模型,它显然是为异步使用而设计的。但是,这不是我有兴趣讨论这个问题的内容。谢谢。
【问题讨论】:
标签: qt c++11 condition-variable qnetworkreply qnetworkrequest