QT多发线程进行数据传输-创新互联

平时的项目程序中,经常需要处理多个串口和网络发送过来的数据,而且数据量还比较大,9600的波特率每秒钟至少1000个字节的数据需要处理并反映到界面上,一开始直接和UI主线程同一个线程,在x86的机器上跑还没问题,毕竟X86的机器最少主频也不会低于1.6G,但是如果数据量再更大或者到了ARM上跑,直接UI卡住不动,想到的解决办法就是用多线程,一个线程负责收数据,一个线程负责处理数据,当协议一样的时候,如果需要将数据解析从串口改为网络端口监听的数据,以前的办法是重新写一个tcp通信进行处理,这个并不是非常合理的办法,毕竟解析协议是一样的,所以自己总结了一个通用的数据处理思路:各种数据接收后排队的形式存入一个全局变量,单独开辟一个线程从这个全局变量中读取第一个数据,处理完则移除第一个数据,Qt中的链表直接提供了一个takeFirst函数,用起来非常爽!用while循环读取,在读取的时候加锁,这样的话就不会冲突了。
雏形:
全局变量文件:

在珲春等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供成都网站建设、成都网站制作 网站设计制作按需定制网站,公司网站建设,企业网站建设,高端网站设计,全网营销推广,成都外贸网站建设,珲春网站建设费用合理。

复制代码

  1. #ifndef APP_H

  2. #define APP_H

  3. #include "qstring.h"

  4. #include "qstringlist.h"

  5. class App

  6. {

  7. public:

  8.     static QStringList list;

  9. };

  10. #endif // APP_H

复制代码

  1. #include "app.h"

  2. QStringList App::list=QStringList();

独立处理数据线程:

复制代码

  1. #ifndef TEST_H

  2. #define TEST_H

  3. #include "qthread.h"

  4. #include "qmutex.h"

  5. class Thread : public QThread

  6. {

  7.     Q_OBJECT

  8. public:

  9.     Thread();

  10.     ~Thread();

  11.     void stop();

  12. protected:

  13.     void run();

  14. private:

  15.     QMutex mutex;

  16.     volatile bool stopped;

  17. signals:

  18.     void readOne(QString txt);

  19. };

  20. #endif // TEST_H

复制代码

  1. #include "thread.h"

  2. #include "app.h"

  3. Thread::Thread()

  4. {

  5. stopped=false;

  6. }

  7. Thread::~Thread()

  8. {

  9. }

  10. void Thread::stop()

  11. {

  12.     stopped=true;

  13. }

  14. void Thread::run()

  15. {

  16.     while(!stopped){

  17.         mutex.lock();

  18.         if (App::list.count()>0){

  19.             QString txt=App::list.takeFirst();

  20.             emit readOne(txt);

  21.         }

  22.         mutex.unlock();

  23.         msleep(1);//不加这句CPU占用率高达50%

  24.     }

  25.     stopped=false;

  26. }

主界面:

复制代码

  1. #ifndef WIDGET_H

  2. #define WIDGET_H

  3. #include

  4. #include "thread.h"

  5. #include "qtimer.h"

  6. namespace Ui {

  7. class frmMain;

  8. }

  9. class frmMain : public QWidget

  10. {

  11.     Q_OBJECT

  12. public:

  13.     explicit frmMain(QWidget *parent = 0);

  14.     ~frmMain();

  15. private slots:

  16.     void writeOne();

  17.     void readOne(QString txt);

  18.     void on_btnAppend_clicked();

  19.     void on_btnThread_clicked();

  20.     void on_btnTimer_clicked();

  21. private:

  22.     Ui::frmMain *ui;

  23.     QTimer *timer;

  24.     Thread *thread;

  25. };

  26. #endif // WIDGET_H

复制代码

  1. #include "frmmain.h"

  2. #include "ui_frmmain.h"

  3. #include "app.h"

  4. #include "qdatetime.h"

  5. #include "qdesktopwidget.h"

  6. #define _TIME_ qPrintable (QTime::currentTime().toString("now : hh:mm:ss:zzz"))

  7. frmMain::frmMain(QWidget *parent) :

  8.     QWidget(parent),

  9.     ui(new Ui::frmMain)

  10. {

  11.     ui->setupUi(this);

  12.     this->showMaximized();

  13.     timer=new QTimer(this);

  14.     timer->setInterval(50);

  15.     connect(timer,SIGNAL(timeout()),this,SLOT(writeOne()));

  16.     thread=new Thread;

  17.     connect(thread,SIGNAL(readOne(QString)),this,SLOT(readOne(QString)));

  18. }

  19. frmMain::~frmMain()

  20. {

  21.     delete ui;

  22. }

  23. void frmMain::writeOne()

  24. {

  25.     App::list.append(_TIME_);

  26. }

  27. void frmMain::readOne(QString txt)

  28. {

  29.     ui->txtOut->append(txt);

  30. }

  31. void frmMain::on_btnAppend_clicked()

  32. {

  33.     App::list.append(ui->txtIn->text());

  34. }

  35. void frmMain::on_btnThread_clicked()

  36. {

  37.     if (ui->btnThread->text()=="start thread"){

  38.         thread->start();

  39.         ui->btnThread->setText("stop thread");

  40.         ui->txtOut->append("start thread ok");

  41.     }else{

  42.         thread->stop();

  43.         ui->btnThread->setText("start thread");

  44.         ui->txtOut->append("stop thread ok");

  45.     }

  46. }

  47. void frmMain::on_btnTimer_clicked()

  48. {

  49.     if (ui->btnTimer->text()=="start timer"){

  50.         timer->start();

  51.         ui->btnTimer->setText("stop timer");

  52.         ui->txtOut->append("start timer ok");

  53.     }else{

  54.         timer->stop();

  55.         ui->btnTimer->setText("start timer");

  56.         ui->txtOut->append("stop timer ok");

  57.     }

  58. }

为了模拟大量数据,我这里开了50毫秒的定时器定时产生当前时间字符串的数据存入全局变量,然后放置了几个按钮用于手动添加字符串和开始停止线程及定时器。
QT多发线程进行数据传输

欢迎提出批评建议以及指点!谢谢!

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


网页标题:QT多发线程进行数据传输-创新互联
转载来源:http://hbruida.cn/article/jdhco.html