|
<div id="cnblogs_post_body">[img]http://www.agoit.com/bbs/file:///C:Documents and SettingsAdministratorApplication DataTencentUsers411506656QQWinTempRichOle7JYN``OK[(GQDG$95DOY_}T.jpg[/img]
开始客户端界面 ThreadNum输入预想最大线程数,以及服务器端IP。 TotalOne--TotalFour 线程随机发送数,用rand()函数获得随机值,具体实现看代码实现,rand()%4+1; 取1-4,客户端发送1, 2, 3, 4 ,自己定义一个协议,用头H,尾e来确保数据传输正确。在此之前,服务器也要检测是否连接上客户端.使用多线程编程,以及QT的信号和槽机制,在客户端建立指定线程数,观察服务器端能承受最多线程值。服务器,客户端都设有跟踪观测窗口。界面是用ui做的,发送1,2,3,4,检测规则及协议可以自己设定,在此程序中,用的是H开头,e结尾,中间夹数字,这样的话,是为了保证数据传输正确,当然程序传值还进一步的加强使用了const,这样,我们只要检测头尾传输接收正确那么就间接保证了传输数据的合法正确性。
此软件也可以计算服务器数据处理能力,以及开最大线程数。
界面输入选项:
每个线程发送数据:m 开线程总数:n 每个数据发送间隔: k (ms) 每开个线程间隔时间: a(ms)
那么数据处理能力v如下计算:
(m*k)/(m*(m*k)/a) = 1000/v v=1000*m/a
当然这个处理能力是在允许开线程范围内,也就是说,我们在计算v时尽量开适合的少些线程。
开最大线程数是需要测试才能知道,不过也需要在数据处理能力范围内。
那么我们先开少线程,计算得v之后,在v范围内测试最大线程数。这就是根本想法。 接下来我们看看操作结果。

PC端,也就是客户端开12个线程。

ARM服务器端可以承受,那么就可以计算此时数据处理能力,用上面推导算法。v=1000*111/123 大概1000左右。

在数据处理范围内开1000个线程。

ARM服务器端显示接收数据和PC客户端不一致,那么说明线程超过了最大线程。

开252个线程,结果还是与ARM服务器端不一致。

且SecureCRT显示有一个线程创建错误。
那么推测减少一个线程。

很明显开251个线程和服务器刚和吻合,且服务器也确实全部接收到。
最终ARM板能开最大线程数为251,显然我们开线程都要考虑余地。
要给服务器留一个越界空间,比如最大能承受线程实际是251,那么我们做成产品或许只能说承受200。这就是余地选择。因为还有许多认为不能预测的因素会影响服务器性能。
部分源码:
客户端:
<div class="cnblogs_code">#include "testthread.h"#include <stdlib.h>#include <time.h>TestThread::TestThread(QObject *parent) : QThread(parent){}TestThread::TestThread(QObject *parent, const char *host, const int DataTime, const long SendThreadData) : //通过构造函数传IP,这个问题调了较久才调好,注意! QThread(parent){ // hostIP = host; PerThreadData = SendThreadData; PerDataTime = DataTime; memset(hostIP,0,sizeof(hostIP)); memcpy(hostIP,host,sizeof(hostIP)); //然后就可以在run()里把hostIP直接当变量connecttohost了}void TestThread::run(){ srand(time(NULL)); socket = new QTcpSocket(); //connect(socket,SIGNAL(readyRead()),this,SLOT(onRead()));// socket->connectToHost("localhost",9090); // QString IP; socket->connectToHost(hostIP,9090); if(!socket->waitForConnected(30000)) { return; } long count,flag; for(count = 0; count < PerThreadData; count++) { flag = rand()%4 +1; switch(flag) { case 1: { socket->write("H1e"); socket->flush(); emit TestSignal(1); }; break; case 2: { socket->write("H2e"); socket->flush(); emit TestSignal(2); }; break; case 3: { socket->write("H3e"); socket->flush(); emit TestSignal(3); }; break; case 4: { socket->write("H4e"); socket->flush(); emit TestSignal(4); }; } msleep(455); //延时100ms } // exec(); //阻止线程退出}//void TestThread::onRead()//{// char buf[100];// memset(buf,0,sizeof(buf));// int length = socket->bytesAvailable();// socket->read(buf,length);// if(buf[0] = 'H')// {// if(buf[2] = 'e')// {// int flag = buf[1] - '0';// switch(flag)// {// case 1:// emit TestSignal(5);// break;// case 2:// emit TestSignal(6);// break;// case 3:// emit TestSignal(7);// break;// case 4:// emit TestSignal(8);// }// }// }//} |
|