Qt采用线程以队列方式实现下发数据
作者:中国好公民st
什么叫做队列方式
在C++中队列是一种常用的数据结构之一,一种特殊的线性表,一般采用先进先出的方式。
很多情况下,在做数据处理时,会根据先来后到的原则进行处理。对于少量数据来说,主进程就可以很快完成,所以不需要用到开线程的方式。将处理处理部分封装成一个函数,直接调用就OK了!
假设,数据处理的时间消耗很大时,继续使用主进程处理的话,肯定会导致页面卡死,为了避免页面卡死,最常用的方式就是开线程。
在程序使用过程中肯定不止一个位置进行数据处理,那么,多次调用数据处理时,如何保证按照触发顺序进行数据解析呢?
这是本篇文章中的重点~
想要按照触发顺序下发,必须要对下发的数据进行排队,这里用到的容器是list。方便添加、删除。
容器:std::list m_list; //存储数据
1.存储需要处理的数据
std::lock_guard<std::mutex> lck(m_mutexRobotData); //上锁添加数据 m_list.push_back(stData);
在进行数据存储时,进行上锁处理,因为在线程中每处理一条数据,需要进行删除,防止出错。
2.开启线程
m_pThreadSendCmd = std::thread(&QWidget::ProcessingThread, this); m_pThreadSendCmd.detach();
这里用到的是C11方式开启线程,有一个弊端,使用功能detach方式后,已经与程序脱离了,想要控制线程的关闭,保守的做法是由参数来控制。
这里,我才用了bool值,当bool = false时,说明线程停止;true表示线程正在运行。
那么,对上述开启线程方式进行修改,如下:
if (m_bRunningRobotCmd == false) { //线程未开启,开启线程 qDebug() << QStringLiteral("开启一个新线程"); m_bRunningRobotCmd = true; m_pThreadSendCmd = std::thread(&QWidget::ProcessingThread, this); m_pThreadSendCmd.detach(); }
3.线程中数据处理
void QWidget::ProcessingThread() { while(m_bRunningRobotCmd) { //线程处理 sleep(200); } //退出while循环,表示线程结束 }
此时,当m_bRunningRobotCmd = true时,表示线程一直在启动,当m_bRunningRobotCmd = false时,立刻停止线程,这时又会遇到一个问题,正在运行的线程中该如何停止呢?
单纯的m_bRunningRobotCmd = false,很显然停止的概率不大,此时,对安全的做法,需要用互斥量的方式,进行停止
对上述线程开启进行修改,如下:
void QWidget::ProcessingThread() { std::lock_guard<std::mutex> lck(m_mutexControlThread); //上锁添加数据 while(m_bRunningRobotCmd) { //线程处理 sleep(200); } //退出while循环,表示线程结束 }
关闭线程方式,如下:
m_bRunningRobotCmd = false; std::lock_guard<std::mutex> lck(m_mutexControlThread); //插入数据之前,首先加锁
首先将bool值更改,再进行加锁。
4.线程内容实现逻辑
当list容器中存在数据时,需要获取第一条数据,处理后删除第一条数据。
实现代码如下:
if(m_list.size() != 0) { //容器中存在有效数据 std::lock_guard<std::mutex> lck(m_mutexRobotData); //上锁添加数据 if(m_list.size() != 0) { //获取第一条有效数据 stData stInfo = m_list.front(); //数据处理 //删除第一条数据 m_list.pop_front(); } }
使用互斥量的方式控制线程增加了安全性,防止崩溃问题。
到此这篇关于Qt采用线程以队列方式实现下发数据的文章就介绍到这了,更多相关Qt队列方式下发数据内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!