qnetworkaccessmanager QNetworkReply - 竞争条件?

时间:2014-06-17 21:45:01

标签: qt network-programming qt5

我有这个与QT相关的问题。 QNetworkAccessManager :: get()返回QNetworkReply指针。然后我可以连接到它的终点位置:

QNetworkReply* r = nam->get(url);
connect(r, SIGNAL(finished()),
            this, SLOT(_finishedThisReply()));

这似乎是正确的做事方式,特别是通过这种方法,您可以使用相同的QNetworkAccessManager对象同时发出请求。但是,我们不是在这里遇到竞争条件吗?如果在完成get和call之间连接完成的信号已被发送怎么办?或者QT是否保证不会发生这种情况?我还没有在QT文档中找到任何相关内容。

1 个答案:

答案 0 :(得分:3)

由于您可以完全控制所运行的线程中发生的事情,因此您的代码在此处运行时可能没有竞争条件。

当然,网络访问管理器的内部可能正在另一个线程中运行。假设在QNetworkManager的实现中发生了以下情况:

Thread A: QNetworkReply* r = nam->get(url);
Thread B: emit r->finished();
Thread A: connect(r, SIGNAL(finished()), ...);

这确实是一个问题。唉,实施可以做其他事情:

Thread A: QNetworkReply* r = nam->get(url);
Thread B: QMetaObject::invokeMethod(r, "finished");
          // equivalent to QCoreApplication::postEvent(r, new QMetaCallEvent(...))
Thread A: connect(r, SIGNAL(finished()), ...);
          ...

在回复的主题中,信号在同步中发出信号。这与第一个变体形成对比,在第一个变体中,信号是异步发射的。

最后,线程A的控制返回到事件循环,并以QMetaCallEvent的形式发送到r的跨线程方法调用,发出信号。

我正在简化,但QNetworkReply的语义是第二个,正确的变体的语义。它“只是有效”。即使网络访问管理器的实现在一个单独的线程中运行,也没有比赛。