原文链接: Markus Goetz - Threaded HTTP inside QNetworkAccessManager
Hi, 我叫Markus,这是我在labs上发布的第一篇blog :-)
自从前段时间,我们集成了一个修改到QNetworkAccessManager中,该修改使HTTP请求运行在独立的线程中,有些朋友要求对此进行澄清,下面请看 :)
该修改背后的原因是(基于Webkit1的)QtWebkit的工作方式。 网络浏览器通常需要做很多工作:
它需要解析HTML和CSS,从JPEG或PNG格式解码图片为可显示的内容。它需要对页面进行布局, 与用户输入进行交互,还需要运行所有我们在Web2.0的美妙世界里拥有的所有Javascript(或者我们已经在3.0的世界了?)
当所有这些工作进行时,如果网络处理与浏览器的其他部分发生在同一个线程中,则网络处理无法有任何进展。 通过网络跟踪我们发现发生了被我们称为“同步点”的现象:当QtWebkit繁忙于主线程并阻塞其事件循环时,新的网络请求不被发送。在最糟情况下, HTTP服务器停止发送新数据。 当你的系统与传统桌面个人电脑相比处理能力较低而网络延时较高时(嗨~手机设备!),这尤其值得关注。
对此有几种解决方案:
1. 将QtWebkit放在线程中,网络保留在用户线程
2. 将整个QNetworkAccessManager放在一个线程中
3. 将QNetworkAccessManager的HTTP代码放在一个线程中
我们使用了第3个方案。
从技术上讲,此方案通过在QNetworkAccessManager内部添加一层来实现。实际的HTTP协议代码丝毫未变,改变的仅仅是QNetworkAccessManager使用它的方式。同样您的代码以及QtWebkit的代码不需要修改。这意味着从Qt 4.8开始,您不需要做任何特殊工作即可从中获益。
如果您现在就想使用它,请看一下我们earth团队的代码仓库并请务必报告bug :)
如果您想看一看代码,其中一个相关的新(内部)类是QHttpThreadDelegate(存在于HTTP线程中)控制HTTP代码。它由(内部类)QNetworkAccessHttpBackend通过信号和槽控制。
附:最近一段时间Qt内部正在发生很多事,而且未来还会继续发生,虽然有谣言与之相悖......当您阅读本文时,我们正在致力于让整个具有Webkit2能力的QtWebkit体验更加异步! :)