curl线程池并发执行
自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取:
https://www.cnblogs.com/bclshuai/p/11380657.html
多线程一直是提高性能和速度的关键技术,继承QT的QRunable类,定义一个线程任务,用QThreadPool线程池去调用url;
3.1 测试程序
采用如下的程序进行测试,采用毫秒计时。
3.1.1 测试主程序
#include <QtCore/QCoreApplication>
#include"RestClientPool.h"
#include "RestClient.h"
#include <QDateTime>
#include <string>
#include <QThreadPool>
#include "MultTask.h"
extern RestClientPool g_restpool;
using namespace std;
//RestClientPool g_restPool;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
///CHttpClient m_shotclient;
RestClientPool m_longClient;
QDateTime StartTime = QDateTime::currentDateTime();
qint64 istarttimems = StartTime.toMSecsSinceEpoch();
/*string strUrl = "http://qt.gtimg.cn/q=sz002415";
string strUrl2= "http://hq.sinajs.cn/list=sz002415";
string strResponse = "";
for (int i=0;i<1000;i++)
{
m_longClient.Get(strUrl2, strResponse);
m_longClient.Get(strUrl, strResponse);
}*/
QThreadPool qThreadPool;
qThreadPool.setMaxThreadCount(10);
for (int i=0;i<1000;i++)
{
MultTask * p = new MultTask();
qThreadPool.start(p);
}
qThreadPool.waitForDone();
QDateTime timeEnd = QDateTime::currentDateTime();
qint64 iendtimems = timeEnd.toMSecsSinceEpoch();
int time = iendtimems - istarttimems;
//int time = timeEnd.toTime_t()- StartTime.toTime_t();
printf("using time %d\n", time);
printf("curl number %d\n ",g_restpool.getcurlsize());
return a.exec();
}
3.1.2 线程类定义
线程类头文件
#ifndef MULTTASK_H
#define MULTTASK_H
#include <QObject>
#include <QRunnable>
#include "RestClientPool.h"
class MultTask : public QObject,public QRunnable
{
Q_OBJECT
public:
MultTask();
~MultTask();
void run();
private:
};
#endif // MULTTASK_H
线程类源文件
#include "MultTask.h"
#include<string>
using namespace std;
RestClientPool g_restpool;//全局变量
MultTask::MultTask()
{
setAutoDelete(true);
}
MultTask::~MultTask()
{
}
void MultTask::run()
{
string strUrl = "http://qt.gtimg.cn/q=sz002415";
string strResponse = "";
g_restpool.Get(strUrl,strResponse);
}
1.1.3 运行测试结果
如下图所示,采用10个线程去调用1000次url1。用时3868毫秒。创建curl的数量是10个,创建的socket连接的数量是10个。平均每次调用时间是0.003868秒。而单线程平均每次调用耗时0.027秒。按理说10个线程,每次调用应该是0.0027秒,但是0.003868秒大于0.0027秒。线程之间的资源竞争和切换也会耗时。而且1000次调用接口中会出现不定数量的错误6,错误码解释是CURLE_COULDNT_RESOLVE_HOST(6)无法bai解析主机。给定的远程主机没有得到解决。可能是多线程访问太快,服务器无法响应。
输出框中显示的创建的10个socket连接:
WSPStartup ===> D:\Project\CurlHighSpeed\Win32\Release\CurlHighSpeed.exe使用链式SPI[WSPConnect] Socket ip 127.0.0.1:54517[WSPConnect] Socket ip 127.0.0.1:54518[WSPConnect] Socket ip 127.0.0.1:54520[WSPConnect] Socket ip 127.0.0.1:54522[WSPConnect] Socket ip 127.0.0.1:54524[WSPConnect] Socket ip 127.0.0.1:54525[WSPConnect] Socket ip 127.0.0.1:54527[WSPConnect] Socket ip 127.0.0.1:54531[WSPConnect] Socket ip 127.0.0.1:54533[WSPConnect] Socket ip 127.0.0.1:54536WSPStartup ===> D:\Project\CurlHighSpeed\Win32\Release\CurlHighSpeed.exe[WSPConnect] Socket ip 127.0.0.1:54540[WSPConnect] Socket ip 127.0.0.1:54539[WSPConnect] Socket ip 127.0.0.1:54542[WSPConnect] Socket ip 127.0.0.1:54544[WSPConnect] Socket ip 127.0.0.1:54546[WSPConnect] Socket ip 127.0.0.1:54551[WSPConnect] Socket ip 127.0.0.1:54553“CurlHighSpeed.exe”
3.1.4 不同线程数量调用耗时
为了研究线程数量和调用耗时的关系,采用不同的线程数量去执行10000次的调用;每次消耗的时间如下所示。随着线程数量的增加,多线程处理速度和性能会大幅提高。但是当线程数量达到一定数量之后,线程池的性能反而下降,这是因为线程之间的竞争资源和线程CPU切换导致的。
线程数量 |
总用时(ms) |
每次用时(ms) |
Curl数量 |
错误数 |
10 |
27690 |
2.7690 |
10 |
6 |
20 |
18080 |
1.808 |
20 |
8 |
50 |
9593 |
0.9593 |
50 |
7 |
100 |
6200 |
0.62 |
100 |
9 |
200 |
7183 |
0.7183 |
200 |
19 |
300 |
12431 |
1.2431 |
300 |
11 |
400 |
11687 |
11687 |
400 |
12 |
500 |
21990 |
2.1990 |
500 |
13 |
3.1.5 测试程序源码下载地址
https://download.****.net/download/baochunlei1/12871489