Qt采用線(xiàn)程以隊(duì)列方式實(shí)現(xiàn)下發(fā)數(shù)據(jù)
什么叫做隊(duì)列方式
在C++中隊(duì)列是一種常用的數(shù)據(jù)結(jié)構(gòu)之一,一種特殊的線(xiàn)性表,一般采用先進(jìn)先出的方式。
很多情況下,在做數(shù)據(jù)處理時(shí),會(huì)根據(jù)先來(lái)后到的原則進(jìn)行處理。對(duì)于少量數(shù)據(jù)來(lái)說(shuō),主進(jìn)程就可以很快完成,所以不需要用到開(kāi)線(xiàn)程的方式。將處理處理部分封裝成一個(gè)函數(shù),直接調(diào)用就OK了!
假設(shè),數(shù)據(jù)處理的時(shí)間消耗很大時(shí),繼續(xù)使用主進(jìn)程處理的話(huà),肯定會(huì)導(dǎo)致頁(yè)面卡死,為了避免頁(yè)面卡死,最常用的方式就是開(kāi)線(xiàn)程。
在程序使用過(guò)程中肯定不止一個(gè)位置進(jìn)行數(shù)據(jù)處理,那么,多次調(diào)用數(shù)據(jù)處理時(shí),如何保證按照觸發(fā)順序進(jìn)行數(shù)據(jù)解析呢?
這是本篇文章中的重點(diǎn)~
想要按照觸發(fā)順序下發(fā),必須要對(duì)下發(fā)的數(shù)據(jù)進(jìn)行排隊(duì),這里用到的容器是list。方便添加、刪除。
容器:std::list m_list; //存儲(chǔ)數(shù)據(jù)
1.存儲(chǔ)需要處理的數(shù)據(jù)
std::lock_guard<std::mutex> lck(m_mutexRobotData); //上鎖添加數(shù)據(jù) m_list.push_back(stData);
在進(jìn)行數(shù)據(jù)存儲(chǔ)時(shí),進(jìn)行上鎖處理,因?yàn)樵诰€(xiàn)程中每處理一條數(shù)據(jù),需要進(jìn)行刪除,防止出錯(cuò)。
2.開(kāi)啟線(xiàn)程
m_pThreadSendCmd = std::thread(&QWidget::ProcessingThread, this); m_pThreadSendCmd.detach();
這里用到的是C11方式開(kāi)啟線(xiàn)程,有一個(gè)弊端,使用功能detach方式后,已經(jīng)與程序脫離了,想要控制線(xiàn)程的關(guān)閉,保守的做法是由參數(shù)來(lái)控制。
這里,我才用了bool值,當(dāng)bool = false時(shí),說(shuō)明線(xiàn)程停止;true表示線(xiàn)程正在運(yùn)行。
那么,對(duì)上述開(kāi)啟線(xiàn)程方式進(jìn)行修改,如下:
if (m_bRunningRobotCmd == false)
{
//線(xiàn)程未開(kāi)啟,開(kāi)啟線(xiàn)程
qDebug() << QStringLiteral("開(kāi)啟一個(gè)新線(xiàn)程");
m_bRunningRobotCmd = true;
m_pThreadSendCmd = std::thread(&QWidget::ProcessingThread, this);
m_pThreadSendCmd.detach();
}3.線(xiàn)程中數(shù)據(jù)處理
void QWidget::ProcessingThread()
{
while(m_bRunningRobotCmd)
{
//線(xiàn)程處理
sleep(200);
}
//退出while循環(huán),表示線(xiàn)程結(jié)束
}
此時(shí),當(dāng)m_bRunningRobotCmd = true時(shí),表示線(xiàn)程一直在啟動(dòng),當(dāng)m_bRunningRobotCmd = false時(shí),立刻停止線(xiàn)程,這時(shí)又會(huì)遇到一個(gè)問(wèn)題,正在運(yùn)行的線(xiàn)程中該如何停止呢?
單純的m_bRunningRobotCmd = false,很顯然停止的概率不大,此時(shí),對(duì)安全的做法,需要用互斥量的方式,進(jìn)行停止
對(duì)上述線(xiàn)程開(kāi)啟進(jìn)行修改,如下:
void QWidget::ProcessingThread()
{
std::lock_guard<std::mutex> lck(m_mutexControlThread); //上鎖添加數(shù)據(jù)
while(m_bRunningRobotCmd)
{
//線(xiàn)程處理
sleep(200);
}
//退出while循環(huán),表示線(xiàn)程結(jié)束
}
關(guān)閉線(xiàn)程方式,如下:
m_bRunningRobotCmd = false; std::lock_guard<std::mutex> lck(m_mutexControlThread); //插入數(shù)據(jù)之前,首先加鎖
首先將bool值更改,再進(jìn)行加鎖。
4.線(xiàn)程內(nèi)容實(shí)現(xiàn)邏輯
當(dāng)list容器中存在數(shù)據(jù)時(shí),需要獲取第一條數(shù)據(jù),處理后刪除第一條數(shù)據(jù)。
實(shí)現(xiàn)代碼如下:
if(m_list.size() != 0)
{
//容器中存在有效數(shù)據(jù)
std::lock_guard<std::mutex> lck(m_mutexRobotData); //上鎖添加數(shù)據(jù)
if(m_list.size() != 0)
{
//獲取第一條有效數(shù)據(jù)
stData stInfo = m_list.front();
//數(shù)據(jù)處理
//刪除第一條數(shù)據(jù)
m_list.pop_front();
}
}
使用互斥量的方式控制線(xiàn)程增加了安全性,防止崩潰問(wèn)題。
到此這篇關(guān)于Qt采用線(xiàn)程以隊(duì)列方式實(shí)現(xiàn)下發(fā)數(shù)據(jù)的文章就介紹到這了,更多相關(guān)Qt隊(duì)列方式下發(fā)數(shù)據(jù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
OpenCV實(shí)現(xiàn)低對(duì)比度圖像臟污區(qū)域檢測(cè)
本文主要介紹了OpenCV實(shí)現(xiàn)低對(duì)比度圖像臟污區(qū)域檢測(cè),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
C語(yǔ)言一看就懂的指針與結(jié)構(gòu)體介紹
指針提供了對(duì)地址操作的一種方法,因此,使用指針可使得C語(yǔ)言能夠更高效地實(shí)現(xiàn)對(duì)計(jì)算機(jī)底層硬件的操作。另外,通過(guò)指針可以更便捷地操作數(shù)組。C數(shù)組允許定義可存儲(chǔ)相同類(lèi)型數(shù)據(jù)項(xiàng)的變量,結(jié)構(gòu)是C編程中另一種用戶(hù)自定義的可用的數(shù)據(jù)類(lèi)型,它允許您存儲(chǔ)不同類(lèi)型的數(shù)據(jù)項(xiàng)2022-04-04
C++11新特性之智能指針(shared_ptr/unique_ptr/weak_ptr)
這篇文章主要介紹了C++11新特性之智能指針,包括shared_ptr, unique_ptr和weak_ptr的基本使用,感興趣的小伙伴們可以參考一下2016-08-08
基于C語(yǔ)言編寫(xiě)一個(gè)簡(jiǎn)單的抽卡小游戲
這篇文章主要為大家介紹了如何利用C語(yǔ)言實(shí)現(xiàn)原神抽卡的小游戲,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-04-04

