当前位置:Gxlcms > 数据库问题 > 在多个线程中使用QNetworkAccessManager

在多个线程中使用QNetworkAccessManager

时间:2021-07-01 10:21:17 帮助过:69人阅读

经研究后发现这是一个线程问题: Tangram会在多个线程发送URL request, 但是在实现时, 却没有考虑线程问题, 程序在运行时得到如下warning:

 

  1. QObject: Cannot create children <span style="color: #0000ff">for</span> a parent that <span style="color: #0000ff">is</span> <span style="color: #0000ff">in</span><span style="color: #000000"> a different thread.
  2. (Parent </span><span style="color: #0000ff">is</span> QNetworkAccessManager(<span style="color: #800080">0x21dcba0</span>), parent<span style="color: #800000">‘</span><span style="color: #800000">s thread is QThread(0x20be1c0), current thread is QThread(0x7f48e0044730)</span>

 

在移植Tangram到Qt平台时, 网络请求使用的是QNetworkAccessManager, QNetworkAccessManager的使用很简单:

 

  1. QNetworkAccessManager *manager = <span style="color: #0000ff">new</span> QNetworkAccessManager(<span style="color: #0000ff">this</span><span style="color: #000000">);
  2. connect(manager, SIGNAL(finished(QNetworkReply</span>*<span style="color: #000000">)), th</span><span style="color: #0000ff">is</span>, SLOT(replyFinished(QNetworkReply*<span style="color: #000000">)));
  3. manager</span>-><span style="color: #0000ff">get</span>(QNetworkRequest(QUrl(<span style="color: #800000">"</span><span style="color: #800000">http://qt-project.org</span><span style="color: #800000">"</span>)));

 

这里碰到的问题是:Tangram可能在多个线程发送URL, 但是QNetworkAccessManager只能在生成它所在的线程中工作, 解决办法是使用Qt的SIGNAL/SLOT机制, 把该URL request post到正确的线程中:

  1. <span style="color: #0000ff">class</span><span style="color: #000000"> URLTaskWorker{
  2. </span><span style="color: #0000ff">public</span><span style="color: #000000">:
  3. URLTaskWorker(){
  4. connect(</span><span style="color: #0000ff">this</span>,SIGNAL(startRequest()),<span style="color: #0000ff">this</span><span style="color: #000000">, SLOT(onRequest()), Qt::QueuedConnection);
  5. }
  6. </span><span style="color: #0000ff">public</span><span style="color: #000000">:
  7. </span><span style="color: #0000ff">void</span><span style="color: #000000"> handleTask(QUrl url){
  8. </span><span style="color: #0000ff">this</span>->url =<span style="color: #000000"> url;
  9. emit StartNewRequest();
  10. }
  11. signals:
  12. </span><span style="color: #0000ff">void</span><span style="color: #000000"> startRequest();
  13. </span><span style="color: #0000ff">private</span><span style="color: #000000"> slots:
  14. </span><span style="color: #0000ff">void</span><span style="color: #000000"> onRequest(){
  15. qnam.</span><span style="color: #0000ff">get</span><span style="color: #000000">(url);
  16. }
  17. </span><span style="color: #0000ff">private</span><span style="color: #000000">:
  18. QNetworkAccessManager qnam;
  19. QUrl url;
  20. };</span>

 

这里要注意的是, 在connect startRequestonRequest时, 要使用Qt::QueuedConnection, 使用默认的Qt::AutoConnection不工作, 参考Qt帮助文档:

  1. <span style="color: #000000">Qt::QueuedConnection
  2. </span><span style="color: #000000">
  3. The slot </span><span style="color: #0000ff">is</span> invoked when control returns to the <span style="color: #0000ff">event</span> loop of the receiver<span style="color: #800000">‘</span><span style="color: #800000">s thread. The slot is executed in the receiver</span><span style="color: #800000">‘</span>s thread.

这也是一个Qt的线程安全的在不同线程间传递消息的方法。

 

在多个线程中使用QNetworkAccessManager

标签:nal   ssm   pos   repo   文档   manage   object   不同   mon   

人气教程排行