Parcourir la source

V1.2.2
1、修复了部分内存泄漏的问题

Apple il y a 3 semaines
Parent
commit
36fefc7cd6

+ 1 - 1
RTPServer/RtpOneRoadThread.cpp

@@ -161,9 +161,9 @@ void RTPOneRoadThread::task()
     m_eventLoop.exec();
     /* 清空数据 */
     clearData();
+    SPDLOG_LOGGER_WARN(m_logger_local, "➢ {} RTP发送数据线程结束 ", m_logBase);
     m_isRunning.store(false);
     m_isStoped.store(true);
-    SPDLOG_LOGGER_WARN(m_logger_local, "➢ {} RTP发送数据线程结束 ", m_logBase);
 }
 
 

+ 1 - 1
RTPServer/RtpServer.cpp

@@ -81,7 +81,7 @@ bool RTPServer::thread_task(int port)
 }
 
 /* 停止线程 */
-void RTPServer::thread_stopBlock()
+void RTPServer::thread_stop_block()
 {
     if(m_eventLoop.isRunning())
     {

+ 1 - 1
RTPServer/RtpServer.h

@@ -39,7 +39,7 @@ public:
      */
     bool thread_task(int port);
     /* 停止线程 */
-    void thread_stopBlock();
+    void thread_stop_block();
 
 
 private slots:

+ 1 - 1
Server/ACAServer.cpp

@@ -36,7 +36,7 @@ ACAServer::~ACAServer()
 {
     if(m_rtpServer != nullptr)
     {
-        m_rtpServer->thread_stopBlock();
+        m_rtpServer->thread_stop_block();
         delete m_rtpServer;
         m_rtpServer = nullptr;
     }

+ 3 - 3
Server/ThreadCalculate/BaseCalculateThread.cpp

@@ -29,11 +29,11 @@ void BaseCalculateThread::thread_task()
     task();
 
     m_isRunning = false;
-    /* 清理资源 */
+    
+    SPDLOG_INFO("★ {} 执行结束", m_logBase);
     /* 设置全局的线程状态 */
     m_threadInfo.threadState = EThreadState::State_Stopped;
     m_isStoped.store(true);
-    SPDLOG_INFO("★ {} 执行结束", m_logBase);
 }
 
 /* 更新线程信息 */
@@ -56,7 +56,7 @@ void BaseCalculateThread::thread_stop()
 }
 
 /* 停止线程 */
-void BaseCalculateThread::thread_stopBlock()
+void BaseCalculateThread::thread_stop_block()
 {
     m_isRunning = false;
     while(m_isStoped.load() == false) 

+ 1 - 1
Server/ThreadCalculate/BaseCalculateThread.h

@@ -32,7 +32,7 @@ public:
     /* 停止线程,只设置个停止标志,不阻塞等待 */
     virtual void thread_stop();
     /* 停止线程 */
-    virtual void thread_stopBlock();
+    virtual void thread_stop_block();
 
     
 

+ 67 - 16
Server/ThreadCalculate/CompareItemThread.cpp

@@ -41,6 +41,33 @@ void CompareItemThread::thread_task()
     }
     SPDLOG_LOGGER_INFO(m_logger, "----------------------------------------------------------------");
 
+    /* --------------------------- 这里模拟线程运行 --------------------------- */
+    m_isRunning.store(true);
+    /* 创建录音通道线程 */
+    for(const auto& road : m_threadInfo.compareItemInfo.mapRoad)
+    {
+        ThreadMan.createRecordThread(road.scRoadInfo, m_threadInfo.compareItemInfo.nID);
+    }
+    while (m_isRunning.load()) 
+    {
+        SPDLOG_LOGGER_TRACE(m_logger, "{} 模拟线程运行中...", m_logBase);
+        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
+    }
+    /* 移除使用到的录音通道 */
+    for(auto& it : m_threadInfo.compareItemInfo.mapRoad)
+    {
+        OneSoundCardPCMInfo_t roadInfo = it.scRoadInfo;
+        if(!ThreadMan.removeRecordThread(roadInfo, m_threadInfo.compareItemInfo.nID))
+        {
+            SPDLOG_LOGGER_ERROR(m_logger, "{} 移除录音通道 {}:{} 失败", m_logBase, roadInfo.strSoundCardName, roadInfo.pcmInfo.strPCMName);
+        }
+    }
+    m_isStoped.store(true);
+    return;
+
+    /* --------------------------------------------------------------------------------- */
+
+
     /* 初始化数据 */
     if(!initData())
     {
@@ -78,9 +105,21 @@ void CompareItemThread::thread_task()
 
     /* 线程结束,清理数据 */
     clearData();
+    if(m_pTimer != nullptr)
+    {
+        m_pTimer->stop();
+        delete m_pTimer;
+        m_pTimer = nullptr;
+    }
+    if(m_pFromMQTT != nullptr)
+    {
+        delete m_pFromMQTT;
+        m_pFromMQTT = nullptr;
+    }
+
+    SPDLOG_LOGGER_WARN(m_logger, "★ {} 线程结束运行", m_logBase);
     m_threadInfo.threadState = EThreadState::State_Stopped;
     m_isStoped = true;
-    SPDLOG_LOGGER_WARN(m_logger, "★ {} 线程结束运行", m_logBase);
 }
 
 
@@ -91,7 +130,7 @@ void CompareItemThread::thread_stop()
     
 }
 
-void CompareItemThread::thread_stopBlock()
+void CompareItemThread::thread_stop_block()
 {
     thread_stop();
     while(!m_isStoped) // 等待线程停止
@@ -155,14 +194,14 @@ void CompareItemThread::timerTask()
     /* -------------------------------------------------------------------------------------
      * 更新对比项信息
      * ------------------------------------------------------------------------------------- */
-    if(updateThreadInfoInternal())
-    {
-        SPDLOG_LOGGER_INFO(m_logger, "{} 暂停对比检测,开始更新对比项信息...");
-        clearData();
-        m_threadInfo.compareItemInfo = m_threadInfoNew.compareItemInfo;
-        initData();
-        SPDLOG_LOGGER_INFO(m_logger, "{} 更新对比项信息完成,继续检测对比");
-    }
+    // if(updateThreadInfoInternal())
+    // {
+    //     SPDLOG_LOGGER_INFO(m_logger, "{} 暂停对比检测,开始更新对比项信息...");
+    //     clearData();
+    //     m_threadInfo.compareItemInfo = m_threadInfoNew.compareItemInfo;
+    //     initData();
+    //     SPDLOG_LOGGER_INFO(m_logger, "{} 更新对比项信息完成,继续检测对比");
+    // }
 
     /* 更新检测时间段 */
     checkDetectPeriod();
@@ -275,6 +314,8 @@ void CompareItemThread::clearData()
     destroyNoiseDetectThreads();
     /* 销毁音量报警线程 */
     destroyCalculateDBThreads();
+    /* 清空创建音量包的线程指针 */
+    m_mapCreateDBThreads.clear();
 
     /* 移除使用到的录音通道 */
     for(auto& it : m_threadInfo.compareItemInfo.mapRoad)
@@ -286,11 +327,16 @@ void CompareItemThread::clearData()
         }
     }
 
-    if(m_pFromMQTT != nullptr)
+    for(auto& it : m_mapRealTimeData)
     {
-        delete m_pFromMQTT; // 删除MQTT对象
-        m_pFromMQTT = nullptr; // 设置为nullptr
+        it.second.clear();
     }
+
+    // if(m_pFromMQTT != nullptr)
+    // {
+    //     delete m_pFromMQTT; // 删除MQTT对象
+    //     m_pFromMQTT = nullptr; // 设置为nullptr
+    // }
 }
 
 /* 定时器槽函数 */
@@ -459,7 +505,7 @@ void CompareItemThread::destroyCompareThreads()
     {
         if(pair.second != nullptr)
         {
-            pair.second->thread_stopBlock(); // 停止线程
+            pair.second->thread_stop_block(); // 停止线程
             delete pair.second;             // 删除线程
             pair.second = nullptr;          // 设置为nullptr
         }
@@ -512,7 +558,7 @@ void CompareItemThread::destroyCalculateDBThreads()
     {
         if(pair.second != nullptr)
         {
-            pair.second->thread_stopBlock(); // 停止线程
+            pair.second->thread_stop_block(); // 停止线程
             delete pair.second;             // 删除线程
             pair.second = nullptr;          // 设置为nullptr
         }
@@ -567,7 +613,7 @@ void CompareItemThread::destroyNoiseDetectThreads()
     {
         if(pair.second != nullptr)
         {
-            pair.second->thread_stopBlock(); // 停止线程
+            pair.second->thread_stop_block(); // 停止线程
             delete pair.second;             // 删除线程
             pair.second = nullptr;          // 设置为nullptr
         }
@@ -600,6 +646,11 @@ bool CompareItemThread::updateResultData()
     bool isAllUpdated = false;
     while(isAllUpdated == false)
     {
+        if(m_isRunning == false)
+        {
+            return false; // 线程停止,直接返回
+        }
+
         std::this_thread::sleep_for(std::chrono::milliseconds(1));
         for(auto& pair : m_mapCDBUpdated)
         {

+ 3 - 1
Server/ThreadCalculate/CompareItemThread.h

@@ -54,11 +54,12 @@ public:
 
     /* 停止线程 */
     void thread_stop() override;
-    void thread_stopBlock() override;
+    void thread_stop_block() override;
 
     /* 设置检测时段 */
     void setDetectPeriod(const DetectPeriodConfig_t& detectPeriod);
 
+
 protected:
     /* 线程功能函数,未使用这个函数 */
     void task() override;
@@ -146,6 +147,7 @@ private:
     std::map<int, NoiseDetectThread*> m_mapNoiseDetectThreads;
     /* 对比项信息线程,这个线程在这里创建,不会和其他对比项复用,int是第二路对比通道的编号 */
     std::map<int, ConsistencyCompareThread*> m_mapCpmsistencyThreads;
+    
     /* 创建音量包的线程指针 */
     std::map<int, CreateDBThread*> m_mapCreateDBThreads;
 

+ 0 - 4
Server/ThreadCalculate/ConsistencyCompareThread.cpp

@@ -263,10 +263,6 @@ void ConsistencyCompareThread::clearData()
     m_pCreateWAVThread1 = nullptr;
     m_pCreateWAVThread2 = nullptr;
 
-    /* 设置标志位 */
-    m_isRunning = false;
-    m_isStoped.store(true);
-    m_threadInfo.threadState = EThreadState::State_Stopped;
 }
 
 /* 比对两个wav文件的一致性 */

+ 3 - 0
Server/ThreadCalculate/NoiseDetectThread.cpp

@@ -199,6 +199,9 @@ void NoiseDetectThread::clearData()
 {
     /* 判断是否还在报警中,如果是,则结束报警 */
     endAlarm();
+
+    /* 删除分配的内存 */
+    
 }
 
 /* 调用动态库检测噪音 */

+ 56 - 40
Server/ThreadManager/ThreadCompareItemManager.cpp

@@ -23,6 +23,7 @@ void ThreadCompareItemManager::thread_compareItem(CalculateThreadInfo_t threadIn
     
     /* 启动线程,就会一直阻塞在这里了 */
     pThread->thread_task();
+   
 }
 
 
@@ -85,26 +86,7 @@ void ThreadCompareItemManager::thread_CompareItemManager()
 
 }
 
-/* 添加对比项实例 */
-void ThreadCompareItemManager::addCompareItemThread(CompareItemThread* pThread)
-{
-    if(pThread == nullptr)
-    {
-        SPDLOG_LOGGER_ERROR(m_logger, "添加对比项线程失败,线程指针为空");
-        return;
-    }
-    
-    std::lock_guard<std::mutex> lock(m_mutexCompareItemThreads);
-    int compareItemID = pThread->getThreadInfo().compareItemInfo.nID;
-    if(m_mapThreads.contains(compareItemID))
-    {
-        SPDLOG_LOGGER_WARN(m_logger, "对比项线程已存在,ID: {}", compareItemID);
-        return; // 对比项线程已存在
-    }
-    
-    m_mapThreads.insert(compareItemID, pThread);
-    SPDLOG_LOGGER_INFO(m_logger, "添加对比项线程成功,ID: {}", compareItemID);
-}
+
 
 /* 通过对比项ID和通道ID获取声卡通道信息 */
 OneSoundCardPCMInfo_t ThreadCompareItemManager::getSoundCardRoadInfo(int compareItemID, int roadNum)
@@ -133,9 +115,9 @@ OneSoundCardPCMInfo_t ThreadCompareItemManager::getSoundCardRoadInfo(int compare
 void ThreadCompareItemManager::do_task()
 {
     /* 如果定时间隔小于10秒,则设置成10秒,一开始小是为了线程开启后立马执行一次 */
-    if(m_pTimer->interval() < 10000)
+    if(m_pTimer->interval() < 2000)
     {
-        m_pTimer->setInterval(10000);
+        m_pTimer->setInterval(2000);
     }
     /* 判断MQTT是否连接成功,未连接则再次连接 */
     if(m_pFromMQTT->connectState() != QMQTT::ConnectionState::STATE_CONNECTED)
@@ -159,6 +141,28 @@ void ThreadCompareItemManager::do_task()
     updateCompareItemInfoToMQTT();
 }
 
+
+/* 添加对比项实例 */
+void ThreadCompareItemManager::addCompareItemThread(CompareItemThread* pThread)
+{
+    if(pThread == nullptr)
+    {
+        SPDLOG_LOGGER_ERROR(m_logger, "添加对比项线程失败,线程指针为空");
+        return;
+    }
+    
+    std::lock_guard<std::mutex> lock(m_mutexCompareItemThreads);
+    int compareItemID = pThread->getThreadInfo().compareItemInfo.nID;
+    if(m_mapThreads.contains(compareItemID))
+    {
+        SPDLOG_LOGGER_WARN(m_logger, "对比项线程已存在,ID: {}", compareItemID);
+        return; // 对比项线程已存在
+    }
+    
+    m_mapThreads.insert(compareItemID, pThread);
+    SPDLOG_LOGGER_INFO(m_logger, "添加对比项线程成功,ID: {}", compareItemID);
+}
+
 /* 更新基础设置信息,如数据库设置,噪音参数等 */
 bool ThreadCompareItemManager::updateBaseSettings()
 {
@@ -194,18 +198,20 @@ void ThreadCompareItemManager::processCompareItemInfo()
         SPDLOG_LOGGER_DEBUG(m_logger, "ThreadCompareItemManager: 获取对比项失败");
         return;
     }
-    
-    checkCompareItemInfo(listNewItems, m_listCreateItems, m_listUpdateItems, m_listDeleteItems);
 
-    SPDLOG_LOGGER_DEBUG(m_logger, "要退出的对比项个数: {}, 要更新的对比项个数: {}, 要创建的对比项个数: {}",
-        m_listDeleteItems.size(), m_listUpdateItems.size(), m_listCreateItems.size());
+    checkCompareItemInfo(listNewItems, m_listCreateItems, m_listDeleteItems);
+
+    SPDLOG_LOGGER_DEBUG(m_logger, "要退出的对比项个数: {}, 要创建的对比项个数: {}",
+        m_listDeleteItems.size(), m_listCreateItems.size());
 
     /* 先删除已消失的对比项信息 */
     processDeleteCompareItemThreads(m_listDeleteItems);
     /* 更新需要更新的线程 */
-    updateRunningThreads(m_listUpdateItems);
+    // updateRunningThreads(m_listUpdateItems);
     /* 再创建新的对比项线程 */
     createNewCompareItemThreads(m_listCreateItems);
+
+    SPDLOG_LOGGER_DEBUG(m_logger, "当前对比项个数: {}", m_mapNowCompareItem.size());
 }
 
 
@@ -213,13 +219,13 @@ void ThreadCompareItemManager::processCompareItemInfo()
  * @brief 处理对比项信息,新获取的和已有的对比,会在这里更新 m_mapNowCompareItem 内容
  * 
  * @param createList 创建列表
- * @param updateList 更新列表,根据对比项ID进行更新信息
+ * @param updateList 更新列表,根据对比项ID进行更新信息,没有更新列表了,对比项有更新就删除重建
  * @param deleteList 删除列表
  */
-void ThreadCompareItemManager::checkCompareItemInfo(QList<CompareItemInfo_t>& newList, QList<CompareItemInfo_t>& createList, QList<CompareItemInfo_t>& updateList, QList<int>& deleteList)
+void ThreadCompareItemManager::checkCompareItemInfo(QList<CompareItemInfo_t>& newList, QList<CompareItemInfo_t>& createList, QList<int>& deleteList)
 {
     createList.clear();
-    updateList.clear();
+    // updateList.clear();
     deleteList.clear();
 
     m_mapNowCompareItem.clear();
@@ -265,14 +271,18 @@ void ThreadCompareItemManager::checkCompareItemInfo(QList<CompareItemInfo_t>& ne
                     deleteList.append(item.nID);
                     continue;
                 }
-                updateList.append(item);
+                // updateList.append(item);
+                deleteList.append(item.nID); // 先删除再创建
+                createList.append(item); // 添加到创建列表
                 continue;
             }
             /* 在对比对比项通道信息 */
             if(!existingItem.isEqualRoads(item))
             {
                 /* 通道信息不同,需要更新 */
-                updateList.append(item);
+                // updateList.append(item);
+                deleteList.append(item.nID); // 先删除再创建
+                createList.append(item); // 添加到创建列表
                 continue;
             }
 
@@ -305,14 +315,14 @@ void ThreadCompareItemManager::checkCompareItemInfo(QList<CompareItemInfo_t>& ne
 
 /**
  * @brief 处理需要删除的对比项线程
- *        1、先处理已经停止的线程
+ *        1、先处理已经停止的线程,理论上不会有这个内容了,在上次循环中已经处理过了
  *        2、再将这次列表中的对比项ID对应的线程设置为停止状态,待到下次循环再删除已经停止完成的线程
  * 
  * @param deleteList 
  */
 void ThreadCompareItemManager::processDeleteCompareItemThreads(const QList<int>& deleteList)
 {
-    /* 先处理已经停止运行的线程 */
+    /* 先处理已经停止运行的线程,是上次循环停止的线程 */
     for(auto it = m_mapThreads.begin(); it != m_mapThreads.end();)
     {
         BaseCalculateThread* pThread = it.value();
@@ -335,14 +345,20 @@ void ThreadCompareItemManager::processDeleteCompareItemThreads(const QList<int>&
     }
 
     /* 停止本次需要停止的线程 */
-    for(auto it : m_mapThreads)
+    for(auto it = m_mapThreads.begin(); it != m_mapThreads.end(); )
     {
-        int compareItemID = it->getThreadInfo().compareItemInfo.nID;
+        int compareItemID = it.value()->getThreadInfo().compareItemInfo.nID;
         if(deleteList.contains(compareItemID))
         {
-            /* 设置线程停止标志 */
-            it->thread_stop();
-            SPDLOG_LOGGER_INFO(m_logger, "对比项线程 {} 设置为停止状态", it->getThreadInfo().compareItemInfo.strName.toStdString());
+            std::string compareItemName = it.value()->getThreadInfo().compareItemInfo.strName.toStdString();
+            /* 设置线程停止标志,阻塞等待线程停止,然后再删除 */
+            it.value()->thread_stop_block();
+            delete it.value();
+            it.value() = nullptr; // 设置为nullptr,防止悬空指针
+            it = m_mapThreads.erase(it); // 从列表中删除
+            SPDLOG_LOGGER_INFO(m_logger, "对比项线程 {} 已删除", compareItemName);
+        }else {
+            ++it;
         }
     }
 }
@@ -378,7 +394,7 @@ bool ThreadCompareItemManager::createNewCompareItemThreads(const QList<CompareIt
 {
     if(createList.isEmpty())
     {
-        SPDLOG_LOGGER_DEBUG(m_logger, "没有新的对比项需要创建");
+        // SPDLOG_LOGGER_DEBUG(m_logger, "没有新的对比项需要创建");
         return true;
     }
 

+ 5 - 3
Server/ThreadManager/ThreadCompareItemManager.h

@@ -25,6 +25,7 @@ class FromMQTT;
 
 
 #define CompareItemManager ThreadCompareItemManager::instance()
+
 class ThreadCompareItemManager : public QObject
 {
     Q_OBJECT
@@ -42,8 +43,7 @@ public:
 
     /* 对比项管理器线程函数 */
     void thread_CompareItemManager();
-    /* 添加对比项实例 */
-    void addCompareItemThread(CompareItemThread* pThread);
+
     /* 通过对比项ID和通道ID获取声卡通道信息 */
     OneSoundCardPCMInfo_t getSoundCardRoadInfo(int compareItemID, int roadNum);
     
@@ -57,6 +57,8 @@ private slots:
     void do_task();
 
 private:
+    /* 添加对比项实例 */
+    void addCompareItemThread(CompareItemThread* pThread);
     /* 更新基础设置信息,如数据库设置,噪音参数等 */
     bool updateBaseSettings();
 
@@ -66,7 +68,7 @@ private:
     /* 处理对比项信息,新获取的和已有的对比 */
     void checkCompareItemInfo(  QList<CompareItemInfo_t>& newList,
                                 QList<CompareItemInfo_t>& createList,
-                                QList<CompareItemInfo_t>& updateList,
+                                // QList<CompareItemInfo_t>& updateList,
                                 QList<int>& deleteList);
 
     /* 处理需要删除的对比项线程 */

+ 74 - 61
Server/ThreadManager/ThreadManager.cpp

@@ -78,61 +78,64 @@ bool ThreadManager::createRecordThread(const OneSoundCardPCMInfo_t& pcmInfo, int
     threadInfo.cardRoadInfo = pcmInfo;
     threadInfo.threadState = EThreadState::State_Inited;
     threadInfo.threadType = EThreadType::Type_CreateWAV;
-    CreateWAVThread* pCreateWAVThread = new CreateWAVThread(threadInfo);
-    if(pCreateWAVThread == nullptr)
-    {
-        SPDLOG_LOGGER_ERROR(m_logger, "{}:{} 创建生成wav小文件线程失败", pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName);
-        // return false; // 创建失败
-    }else 
-    {
-        CPPTP.add_task(&CreateWAVThread::thread_task, pCreateWAVThread);
-        std::lock_guard<std::mutex> lock(m_mutexCreateWAVThreads);
-        m_createWAVThreads.push_back(pCreateWAVThread);
-    }
+    // CreateWAVThread* pCreateWAVThread = new CreateWAVThread(threadInfo);
+    // if(pCreateWAVThread == nullptr)
+    // {
+    //     SPDLOG_LOGGER_ERROR(m_logger, "{}:{} 创建生成wav小文件线程失败", pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName);
+    //     // return false; // 创建失败
+    // }else 
+    // {
+    //     CPPTP.add_task(&CreateWAVThread::thread_task, pCreateWAVThread);
+    //     std::lock_guard<std::mutex> lock(m_mutexCreateWAVThreads);
+    //     m_createWAVThreads.push_back(pCreateWAVThread);
+    // }
     
 
     /* 创建计算音量的线程 */
     threadInfo.threadType = EThreadType::Type_CreateDB;
-    CreateDBThread* pCreateDBThread = new CreateDBThread(threadInfo);
-    if(pCreateDBThread == nullptr)
-    {
-        SPDLOG_LOGGER_ERROR(m_logger, "{}:{} 创建计算音量线程失败", pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName);
-        // return false; // 创建失败
-    }else 
-    {
-        CPPTP.add_task(&CreateDBThread::thread_task, pCreateDBThread);
-        std::lock_guard<std::mutex> lock(m_mutexCreateDBThreads);
-        m_createDBThreads.push_back(pCreateDBThread);
-    }
+    // CreateDBThread* pCreateDBThread = new CreateDBThread(threadInfo);
+    // if(pCreateDBThread == nullptr)
+    // {
+    //     SPDLOG_LOGGER_ERROR(m_logger, "{}:{} 创建计算音量线程失败", pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName);
+    //     // return false; // 创建失败
+    // }else 
+    // {
+    //     CPPTP.add_task(&CreateDBThread::thread_task, pCreateDBThread);
+    //     std::lock_guard<std::mutex> lock(m_mutexCreateDBThreads);
+    //     m_createDBThreads.push_back(pCreateDBThread);
+    // }
 
     /* 创建生成长文件的线程 */
     threadInfo.threadType = EThreadType::Type_CreateLongWAV;
-    CreateRecordFileThread* pCreateLongWAVThread = new CreateRecordFileThread(threadInfo);
-    if(pCreateLongWAVThread == nullptr)
-    {
-        SPDLOG_LOGGER_ERROR(m_logger, "{}:{} 创建生成长文件线程失败", pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName);
-        // return false; // 创建失败
-    }else 
-    {
-        CPPTP.add_task(&CreateRecordFileThread::thread_task, pCreateLongWAVThread);
-        std::lock_guard<std::mutex> lock(m_mutexCreateLongWAVThreads);
-        m_createLongWAVThreads.push_back(pCreateLongWAVThread);
-    }
-    
-    /* 创建发送RTP数据的线程 */
-    threadInfo.threadType = EThreadType::Type_RtpSend;
-    CPPTP.add_task(&ThreadManager::thread_RTPSend, threadInfo);
-
-    // RTPOneRoadThread* pRtpSendThread = new RTPOneRoadThread(threadInfo);
-    // if(pRtpSendThread == nullptr) 
+    // CreateRecordFileThread* pCreateLongWAVThread = new CreateRecordFileThread(threadInfo);
+    // if(pCreateLongWAVThread == nullptr)
     // {
-    //     SPDLOG_LOGGER_ERROR(m_logger, "{}:{} 创建发送RTP数据线程失败", pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName);
+    //     SPDLOG_LOGGER_ERROR(m_logger, "{}:{} 创建生成长文件线程失败", pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName);
+    //     // return false; // 创建失败
     // }else 
     // {
-    //     CPPTP.add_task(&RTPOneRoadThread::threadTask, pRtpSendThread);
-    //     std::lock_guard<std::mutex> lock(m_mutexRtpSendThreads);
-    //     m_rtpSendThreads.push_back(pRtpSendThread);
+    //     CPPTP.add_task(&CreateRecordFileThread::thread_task, pCreateLongWAVThread);
+    //     std::lock_guard<std::mutex> lock(m_mutexCreateLongWAVThreads);
+    //     m_createLongWAVThreads.push_back(pCreateLongWAVThread);
     // }
+    
+    /* 创建发送RTP数据的线程 */
+    threadInfo.threadType = EThreadType::Type_RtpSend;
+    // CPPTP.add_task(&ThreadManager::thread_RTPSend, threadInfo);
+
+    /* 创建分派数据线程 */
+    threadInfo.threadType = EThreadType::Type_AssignSrcData;
+    AssignSrcDataThread* pAssignSrcDataThread = new AssignSrcDataThread(threadInfo);
+    if(pAssignSrcDataThread == nullptr)
+    {
+        SPDLOG_LOGGER_ERROR(m_logger, "{}:{} 创建分派数据线程失败", pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName);
+        // return false; // 创建失败
+    }else
+    {
+        CPPTP.add_task(&AssignSrcDataThread::thread_task, pAssignSrcDataThread);
+        std::lock_guard<std::mutex> lock(m_mutexAssignSrcDataThreads);
+        m_assignSrcDataThreads.push_back(pAssignSrcDataThread);
+    }
 
     /* 创建录音线程 */
     threadInfo.threadType = EThreadType::Type_RecordSrc;
@@ -148,22 +151,12 @@ bool ThreadManager::createRecordThread(const OneSoundCardPCMInfo_t& pcmInfo, int
         m_recordThreads.push_back(pRecordThread);
     }
 
-    /* 创建分派数据线程 */
-    threadInfo.threadType = EThreadType::Type_AssignSrcData;
-    AssignSrcDataThread* pAssignSrcDataThread = new AssignSrcDataThread(threadInfo);
-    if(pAssignSrcDataThread == nullptr)
-    {
-        SPDLOG_LOGGER_ERROR(m_logger, "{}:{} 创建分派数据线程失败", pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName);
-        // return false; // 创建失败
-    }else
-    {
-        CPPTP.add_task(&AssignSrcDataThread::thread_task, pAssignSrcDataThread);
-        std::lock_guard<std::mutex> lock(m_mutexAssignSrcDataThreads);
-        m_assignSrcDataThreads.push_back(pAssignSrcDataThread);
-    }
+    
 
     /* 录音线程创建成功,增加引用计数 */
     m_mapRecordThreadRefCount[pcmInfo.pcmInfo.strPCMName].push_back(compareItemID);
+    // SPDLOG_LOGGER_INFO(m_logger, "{}:{} 录音线程创建成功,map Size: {}, 当前引用计数: {}",
+    //     pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName, m_mapRecordThreadRefCount.size(), m_mapRecordThreadRefCount[pcmInfo.pcmInfo.strPCMName].size());
 
     return true;
 }
@@ -175,8 +168,9 @@ bool ThreadManager::createRecordThread(const OneSoundCardPCMInfo_t& pcmInfo, int
 bool ThreadManager::removeRecordThread(const OneSoundCardPCMInfo_t& pcmInfo, int compareItemID)
 {
     std::unique_lock<std::mutex> lock(m_mutexRecordThreadRefCount);
+    // SPDLOG_LOGGER_WARN(m_logger, "{}:{} 准备销毁录音线程, map Size: {}", pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName, m_mapRecordThreadRefCount.size());
     /* 先查找这个引用计数是否存在 */
-    int refCount = 0;
+    int refCount = -1;
     for(auto& pair : m_mapRecordThreadRefCount)
     {
         if(pair.first == pcmInfo.pcmInfo.strPCMName)
@@ -200,7 +194,12 @@ bool ThreadManager::removeRecordThread(const OneSoundCardPCMInfo_t& pcmInfo, int
         SPDLOG_LOGGER_INFO(m_logger, "{} 录音线程引用计数减少,当前计数: {}", logBase, refCount);
         return true;
     }
-    SPDLOG_LOGGER_INFO(m_logger, "{} 录音线程引用计数为0,即将停止该录音通道的所有线程", logBase);
+    else if(refCount < 0) 
+    {
+        SPDLOG_LOGGER_WARN(m_logger, "{} 录音线程未找到,可能已经释放", logBase);
+        return true;
+    }
+    SPDLOG_LOGGER_WARN(m_logger, "{} 录音线程引用计数为0,即将停止该录音通道的所有线程", logBase);
     
     /* 引用计数为0,停止该录音通道的所有线程 */
     /* 停止录音线程 */
@@ -321,6 +320,7 @@ void ThreadManager::thread_destroyeRecordThread()
         /* 没有需要销毁的线程 */
         return;
     }
+    SPDLOG_LOGGER_INFO(m_logger, "{} 准备销毁录音线程...", m_logBase);
     /* 销毁录音线程 */
     {
         std::lock_guard<std::mutex> lock(m_mutexRecordThreads);
@@ -333,6 +333,8 @@ void ThreadManager::thread_destroyeRecordThread()
                 if(EThreadState::State_Stopped == threadState ||
                    EThreadState::State_Error == threadState )
                 {
+                    SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁录音线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName, 
+                                        pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
                     auto pRecordThread = dynamic_cast<RecordThread*>(pThread);
                     delete pRecordThread; // 删除线程
                     pThread = nullptr;
@@ -357,6 +359,8 @@ void ThreadManager::thread_destroyeRecordThread()
                 if(EThreadState::State_Stopped == threadState ||
                    EThreadState::State_Error == threadState )
                 {
+                    SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁分派数据线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName, 
+                                        pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
                     auto pAssignSrcDataThread = dynamic_cast<AssignSrcDataThread*>(pThread);
                     delete pAssignSrcDataThread; // 删除线程
                     pThread = nullptr;
@@ -381,6 +385,8 @@ void ThreadManager::thread_destroyeRecordThread()
                 if(EThreadState::State_Stopped == threadState ||
                    EThreadState::State_Error == threadState )
                 {
+                    SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁 CreateWAV 线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName, 
+                                        pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
                     auto pCreateWAVThread = dynamic_cast<CreateWAVThread*>(pThread);
                     delete pCreateWAVThread; // 删除线程
                     pThread = nullptr;
@@ -405,6 +411,8 @@ void ThreadManager::thread_destroyeRecordThread()
                 if(EThreadState::State_Stopped == threadState ||
                    EThreadState::State_Error == threadState )
                 {
+                    SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁 CreateDB 线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName, 
+                                        pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
                     auto pCreateDBThread = dynamic_cast<CreateDBThread*>(pThread);
                     delete pCreateDBThread; // 删除线程
                     pThread = nullptr;
@@ -429,6 +437,8 @@ void ThreadManager::thread_destroyeRecordThread()
                 if(EThreadState::State_Stopped == threadState ||
                    EThreadState::State_Error == threadState )
                 {
+                    SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁 RecordFile 线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName, 
+                                        pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
                     auto pCreateLongWAVThread = dynamic_cast<CreateRecordFileThread*>(pThread);
                     delete pCreateLongWAVThread; // 删除线程
                     pThread = nullptr;
@@ -453,6 +463,8 @@ void ThreadManager::thread_destroyeRecordThread()
                 if(EThreadState::State_Stopped == threadState ||
                    EThreadState::State_Error == threadState )
                 {
+                    SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁 RTP Send 线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName, 
+                                        pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
                     auto pRtpSendThread = dynamic_cast<RTPOneRoadThread*>(pThread);
                     delete pRtpSendThread; // 删除线程
                     pThread = nullptr;
@@ -467,6 +479,7 @@ void ThreadManager::thread_destroyeRecordThread()
 
     /* 销毁标志位置为false */
     m_isDestroyeRecordThread.store(false);
+    SPDLOG_LOGGER_INFO(m_logger, "{} 录音线程销毁完成", m_logBase);
 }
 
 
@@ -681,7 +694,7 @@ CreateRecordFileThread* ThreadManager::getCreateRecordFileThread(std::string pcm
 //     if(m_referCountConsistencyCompare <= 0)
 //     {
 //         /* 停止线程,并一直等待其停止 */
-//         pThreadToRemove->thread_stopBlock();
+//         pThreadToRemove->thread_stop_block();
 //         m_listConsistencyCompareThreads.remove(pThreadToRemove); // 从列表中移除
 //         delete pThreadToRemove; // 删除线程
 //         pThreadToRemove = nullptr;
@@ -816,7 +829,7 @@ CreateRecordFileThread* ThreadManager::getCreateRecordFileThread(std::string pcm
 //     {
 //         SPDLOG_LOGGER_INFO(m_logger, "{}:{} 噪音检测线程引用计数为0,准备销毁该线程",
 //                     roadInfo.strSoundCardName.toStdString(), roadInfo.roadInfo.nRoadNum);
-//         pThreadToRemove->thread_stopBlock(); // 停止线程
+//         pThreadToRemove->thread_stop_block(); // 停止线程
 //         m_listNoiseDetectThreads.remove(pThreadToRemove); // 从列表中移除
 //         delete pThreadToRemove; // 删除线程
 //         pThreadToRemove = nullptr;

+ 1 - 1
Server/ThreadManager/ThreadWriteDBManager.cpp

@@ -52,7 +52,7 @@ void ThreadWriteDBManager::thread_stop()
     m_isRunning = false; // 设置线程停止标志位
 }
 
-void ThreadWriteDBManager::thread_stopBlock()
+void ThreadWriteDBManager::thread_stop_block()
 {
     thread_stop();
     while(m_threadState != EThreadState::State_Stopped) // 等待线程停止

+ 1 - 1
Server/ThreadManager/ThreadWriteDBManager.h

@@ -58,7 +58,7 @@ public:
     void thread_task();
     /* 停止线程 */
     void thread_stop();
-    void thread_stopBlock();
+    void thread_stop_block();
     /* 获取线程状态 */
     EThreadState getThreadState() const { return m_threadState; }
 

+ 52 - 52
Server/ThreadRecord/AssignSrcDataThread.cpp

@@ -58,13 +58,8 @@ void AssignSrcDataThread::thread_stop()
 void AssignSrcDataThread::thread_stop_block()
 {
     thread_stop();
-    while(true)
+    while(m_isStoped.load() == false)
     {
-        if(m_isStoped.load())
-        {
-            break;
-        }
-
         std::this_thread::sleep_for(std::chrono::milliseconds(1));
     }
 }
@@ -127,8 +122,6 @@ void AssignSrcDataThread::task()
         SPDLOG_LOGGER_ERROR(m_logger, "{} 获取音频处理线程失败", m_logBase);
         return;
     }
-    /* 将自身设置到录音线程中 */
-    m_pThreadRecord->setAssignSrcDataThread(this);
     
     m_isRunning = true;
     while(m_isRunning)
@@ -146,6 +139,11 @@ void AssignSrcDataThread::task()
          * 分派实时数据
          *------------------------------------------------------------------------*/
         /* 获取最新的数据,给其添加开始时间戳 */
+        if(m_listAudioSrcData.size() == 0)
+        {
+            /* 在线程退出的时候会唤醒上面的条件变量,此时队列可能是空的 */
+            continue;
+        }
         auto latestData = m_listAudioSrcData.back();
         if(latestData == nullptr || latestData->isEmpty())
         {
@@ -215,20 +213,25 @@ bool AssignSrcDataThread::initData()
 /* 清理数据 */
 void AssignSrcDataThread::clearData()
 {
+    std::unique_lock<std::mutex> lock(m_mutexDataUpdate);
     if(m_dispatchSrcData != nullptr)
     {
         delete m_dispatchSrcData;
         m_dispatchSrcData = nullptr;
     }
-    // if(m_pCurrentSrcData != nullptr)
-    // {
-    //     delete m_pCurrentSrcData;
-    //     m_pCurrentSrcData = nullptr;
-    // }
-    
     
+    for(auto& it : m_listAudioSrcData)
+    {
+        if(it != nullptr)
+        {
+            delete it;
+            it = nullptr;
+        }
+    }
+    m_listAudioSrcData.clear();
 }
 
+
 /**
  * @brief 获取需要分派数据的线程
  *        1、获取的时候按照线程实时性、重要性等因素进行排序获取
@@ -242,46 +245,43 @@ bool AssignSrcDataThread::getDispatchThread()
     /* 根据生成数据文件的类型顺序获取,循环获取,直到所有的线程都获取到 */
 
     /* 先获取生成wav小文件的线程 */
-    auto pWavThread = ThreadMan.findRecordThread(EThreadType::Type_CreateWAV, m_threadInfo.cardRoadInfo.pcmInfo.strPCMName);
-    if(pWavThread != nullptr)
-    {
-        // m_listDispatchThreads.push_back(dynamic_cast<BaseRecordThread*>(pWavThread));
-        m_pThreadCreateWAV = dynamic_cast<CreateWAVThread*>(pWavThread);
-    }
-    /* 获取生成音量和反相数据的线程 */
-    auto pDBAndPhaseThread = ThreadMan.findRecordThread(EThreadType::Type_CreateDB, m_threadInfo.cardRoadInfo.pcmInfo.strPCMName);
-    if(pDBAndPhaseThread != nullptr)
-    {
-        // m_listDispatchThreads.push_back(dynamic_cast<BaseRecordThread*>(pDBAndPhaseThread));
-        m_pThreadCreateDB = dynamic_cast<CreateDBThread*>(pDBAndPhaseThread);
-    }
-    /* 获取生成长文件的线程 */
-    auto pLongFileThread = ThreadMan.findRecordThread(EThreadType::Type_CreateLongWAV, m_threadInfo.cardRoadInfo.pcmInfo.strPCMName);
-    if(pLongFileThread != nullptr )
-    {
-        // m_listDispatchThreads.push_back(dynamic_cast<BaseRecordThread*>(pLongFileThread));
-        m_pThreadCreateLongFile = dynamic_cast<CreateRecordFileThread*>(pLongFileThread);
-    }
-    /* 获取发送RTP数据的线程 */
-    m_rtpSenderThread = ThreadMan.findRecordThread(EThreadType::Type_RtpSend, m_threadInfo.cardRoadInfo.pcmInfo.strPCMName);
-    if(m_rtpSenderThread == nullptr)
-    {
-        // SPDLOG_LOGGER_ERROR(m_logger, "{} 获取RTP发送线程失败", m_logBase);
-        // return false;
-    }
+    // auto pWavThread = ThreadMan.findRecordThread(EThreadType::Type_CreateWAV, m_threadInfo.cardRoadInfo.pcmInfo.strPCMName);
+    // if(pWavThread != nullptr)
+    // {
+    //     m_pThreadCreateWAV = dynamic_cast<CreateWAVThread*>(pWavThread);
+    // }
+    // /* 获取生成音量和反相数据的线程 */
+    // auto pDBAndPhaseThread = ThreadMan.findRecordThread(EThreadType::Type_CreateDB, m_threadInfo.cardRoadInfo.pcmInfo.strPCMName);
+    // if(pDBAndPhaseThread != nullptr)
+    // {
+    //     m_pThreadCreateDB = dynamic_cast<CreateDBThread*>(pDBAndPhaseThread);
+    // }
+    // /* 获取生成长文件的线程 */
+    // auto pLongFileThread = ThreadMan.findRecordThread(EThreadType::Type_CreateLongWAV, m_threadInfo.cardRoadInfo.pcmInfo.strPCMName);
+    // if(pLongFileThread != nullptr )
+    // {
+    //     m_pThreadCreateLongFile = dynamic_cast<CreateRecordFileThread*>(pLongFileThread);
+    // }
+    // /* 获取发送RTP数据的线程 */
+    // m_rtpSenderThread = ThreadMan.findRecordThread(EThreadType::Type_RtpSend, m_threadInfo.cardRoadInfo.pcmInfo.strPCMName);
+    // if(m_rtpSenderThread == nullptr)
+    // {
+    //     // SPDLOG_LOGGER_ERROR(m_logger, "{} 获取RTP发送线程失败", m_logBase);
+    //     // return false;
+    // }
 
     /* 最后获取录音线程信息,如果获取不到则一直获取 */
-    while(true)
-    {
-        auto pThreadBase = ThreadMan.findRecordThread(EThreadType::Type_RecordSrc, m_threadInfo.cardRoadInfo.pcmInfo.strPCMName);
-        if(pThreadBase != nullptr)
-        {
-            m_pThreadRecord = dynamic_cast<RecordThread*>(pThreadBase);
-            break; // 找到录音线程了
-        }
-        /* 如果没有找到录音线程,则等待一段时间再继续查找 */
-        std::this_thread::sleep_for(std::chrono::milliseconds(5));
-    }
+    // while(true)
+    // {
+    //     auto pThreadBase = ThreadMan.findRecordThread(EThreadType::Type_RecordSrc, m_threadInfo.cardRoadInfo.pcmInfo.strPCMName);
+    //     if(pThreadBase != nullptr)
+    //     {
+    //         m_pThreadRecord = dynamic_cast<RecordThread*>(pThreadBase);
+    //         break; // 找到录音线程了
+    //     }
+    //     /* 如果没有找到录音线程,则等待一段时间再继续查找 */
+    //     std::this_thread::sleep_for(std::chrono::milliseconds(5));
+    // }
 
     return true;
 }

+ 1 - 1
Server/ThreadRecord/AssignSrcDataThread.h

@@ -86,7 +86,7 @@ private:
     QDateTime m_lastDataEndTime;                        /* 上次数据的结束时间 */
 
     /* ---------------------- 录音线程指针 ---------------------- */
-    RecordThread* m_pThreadRecord = nullptr;            /* 录音线程 */
+    // RecordThread* m_pThreadRecord = nullptr;            /* 录音线程 */
 
     /* ---------------------- RTP发送相关变量 ---------------------- */
     BaseRecordThread* m_rtpSenderThread = nullptr;      /* RTP发送线程 */

+ 10 - 10
Server/ThreadRecord/AudioRecord/AudioRecord.cpp

@@ -236,17 +236,17 @@ bool AudioRecord::openRecordChannel(const std::string &deviceName)
 		return false;
 	}
 	/* 设置缓冲区大小 */
-	if ((err = snd_pcm_hw_params_set_buffer_size(m_captureHandle, hw_params, buffer_size)) < 0) {
-		SPDLOG_ERROR("无法设置缓冲区大小: {}", snd_strerror(err));
-		goto snd_free;
-		return false;
-	}
+	// if ((err = snd_pcm_hw_params_set_buffer_size(m_captureHandle, hw_params, buffer_size)) < 0) {
+	// 	SPDLOG_ERROR("无法设置缓冲区大小: {}", snd_strerror(err));
+	// 	goto snd_free;
+	// 	return false;
+	// }
 	/* 设置周期大小 */
-	if ((err = snd_pcm_hw_params_set_period_size(m_captureHandle, hw_params, period_size, 0)) < 0) {
-		SPDLOG_ERROR("无法设置周期大小: {}", snd_strerror(err));
-		goto snd_free;
-		return false;
-	}
+	// if ((err = snd_pcm_hw_params_set_period_size(m_captureHandle, hw_params, period_size, 0)) < 0) {
+	// 	SPDLOG_ERROR("无法设置周期大小: {}", snd_strerror(err));
+	// 	goto snd_free;
+	// 	return false;
+	// }
 	/* 应用硬件参数 */
 	if ((err = snd_pcm_hw_params(m_captureHandle, hw_params)) < 0) {
 		SPDLOG_ERROR("无法应用硬件参数: {}", snd_strerror(err));

+ 3 - 5
Server/ThreadRecord/BaseRecordThread.cpp

@@ -39,6 +39,8 @@ void BaseRecordThread::thread_task()
     m_threadInfo.threadState = EThreadState::State_Stopped;
 
     m_isRunning.store(false);
+
+    /* m_isStoped必须放在最后 */
     m_isStoped.store(true);
 }
 
@@ -58,12 +60,8 @@ void BaseRecordThread::thread_stop_block()
     }
 
     /* 等待退出 */
-    while(true)
+    while(m_isStoped.load() == false)
     {
-        if(m_isStoped.load())
-        {
-            break;
-        }
         std::this_thread::sleep_for(std::chrono::milliseconds(1));
     }
 }

+ 49 - 27
Server/ThreadRecord/CreateDBThread.cpp

@@ -108,8 +108,8 @@ bool CreateDBThread::getLatestResult(OneSecondData& resultData)
         // SPDLOG_LOGGER_ERROR(m_logger, "{} 获取最新结果失败,传入的时间戳为空", m_logBase);
         return false;
     }
-    std::lock_guard<std::mutex> lock(m_queueResultData->mutex);
-    auto lastSecondData = m_queueResultData->back();
+    std::lock_guard<std::mutex> lock(m_queueResultData.mutex);
+    auto lastSecondData = m_queueResultData.back();
     if(lastSecondData == nullptr)
     {
         SPDLOG_LOGGER_ERROR(m_logger, "{} 获取最新结果失败,结果队列为空", m_logBase);
@@ -127,8 +127,8 @@ bool CreateDBThread::getLatestResult(OneSecondData& resultData)
 /* 获取最新的结果,让整个环形队列相等 */
 bool CreateDBThread::getLatestResult(RingQueueManualMutex<OneSecondData*>& resultQueue)
 {
-    std::lock_guard<std::mutex> lock(m_queueResultData->mutex);
-    if(m_queueResultData->isEmpty())
+    std::lock_guard<std::mutex> lock(m_queueResultData.mutex);
+    if(m_queueResultData.isEmpty())
     {
         // SPDLOG_LOGGER_TRACE(m_logger, "{} 获取最新数据,数据队列为空", m_logBase);
         return false;
@@ -137,9 +137,9 @@ bool CreateDBThread::getLatestResult(RingQueueManualMutex<OneSecondData*>& resul
     if(resultQueue.isEmpty())
     {
         SPDLOG_LOGGER_DEBUG(m_logger, "{} 获取最新数据,目标队列为空,拷贝整个结果队列", m_logBase);
-        for(int i = 0; i < m_queueResultData->QueueSize(); ++i)
+        for(int i = 0; i < m_queueResultData.QueueSize(); ++i)
         {
-            OneSecondData* data = m_queueResultData->at(i);
+            OneSecondData* data = m_queueResultData.at(i);
             if(data != nullptr)
             {
                 OneSecondData* newData = new OneSecondData(*data); // 深拷贝
@@ -152,10 +152,10 @@ bool CreateDBThread::getLatestResult(RingQueueManualMutex<OneSecondData*>& resul
     /* 队列不为空,查找队列中相等的位置,拷贝后面的数据,不拷贝整个队列,减少开销
      * 这里直接从最新的数据往前找 */
     auto itBack = resultQueue.back();
-    int index = m_queueResultData->QueueSize() - 1;
+    int index = m_queueResultData.QueueSize() - 1;
     while(index >= 0)
     {
-        OneSecondData* data = m_queueResultData->at(index);
+        OneSecondData* data = m_queueResultData.at(index);
         if(data == nullptr)
         {
             --index;
@@ -171,7 +171,7 @@ bool CreateDBThread::getLatestResult(RingQueueManualMutex<OneSecondData*>& resul
     if(index < 0)
     {
         SPDLOG_LOGGER_WARN(m_logger, "{} 获取最新数据失败,未找到相等的时间戳,将清空队列,拷贝全部数据", m_logBase);
-        SPDLOG_LOGGER_WARN(m_logger, "队列大小: {}, 目标队列大小: {}", m_queueResultData->QueueSize(), resultQueue.QueueSize());
+        SPDLOG_LOGGER_WARN(m_logger, "队列大小: {}, 目标队列大小: {}", m_queueResultData.QueueSize(), resultQueue.QueueSize());
         /* 清空目标队列,将所有的数据全部拷贝 */
         while(!resultQueue.isEmpty())
         {
@@ -183,9 +183,9 @@ bool CreateDBThread::getLatestResult(RingQueueManualMutex<OneSecondData*>& resul
             }
         }
         /* 拷贝全部数据 */
-        for(int i = 0; i < m_queueResultData->QueueSize(); ++i)
+        for(int i = 0; i < m_queueResultData.QueueSize(); ++i)
         {
-            OneSecondData* data = m_queueResultData->at(i);
+            OneSecondData* data = m_queueResultData.at(i);
             if(data != nullptr)
             {
                 OneSecondData* newData = new OneSecondData(*data); // 深拷贝
@@ -195,16 +195,16 @@ bool CreateDBThread::getLatestResult(RingQueueManualMutex<OneSecondData*>& resul
 
         return true;
     }
-    else if(index == m_queueResultData->QueueSize() - 1)
+    else if(index == m_queueResultData.QueueSize() - 1)
     {
         // 已经是最新的数据了,不需要拷贝
         // SPDLOG_LOGGER_DEBUG(m_logger, "{} 获取最新数据,已经是最新的数据了", m_logBase);
         return false;
     }
     /* 拷贝数据 */
-    for(; index < m_queueResultData->QueueSize(); ++index)
+    for(; index < m_queueResultData.QueueSize(); ++index)
     {
-        OneSecondData* data = m_queueResultData->at(index);
+        OneSecondData* data = m_queueResultData.at(index);
         if(data == nullptr)
         {
             continue;
@@ -394,12 +394,11 @@ bool CreateDBThread::initData()
     m_oneDBLengthOfSrcData = m_sampleRate / VOLUME_INFO_NUM;
     m_singleDataLength = m_oneSecondSize / m_numChannels;
 
-    /* 计算音量和反相的环形队列元素数目,默认是180个,即180秒 */
-    // m_queueAudioDataCapacity = queueSize; 
-    m_queueResultData = new RingQueueManualMutex<OneSecondData*>(queueSize);
-    m_queueResultData->mutex.lock();
-    m_queueResultData->setDefaultValue(nullptr);
-    m_queueResultData->mutex.unlock();
+    /* 计算音量的环形队列元素数目,默认是180个,即180秒 */
+    m_queueResultData.mutex.lock();
+    m_queueResultData.setDefaultValue(nullptr);
+    m_queueResultData.setQueueCapacity(queueSize);
+    m_queueResultData.mutex.unlock();
 
     m_numMaxResultData = 60;
 
@@ -419,11 +418,34 @@ void CreateDBThread::clearData()
             data = nullptr;
         }
     }
-    // if(m_remainData != nullptr)
-    // {
-    //     delete m_remainData;
-    //     m_remainData = nullptr;
-    // }
+    
+    std::lock_guard<std::mutex> lock(m_queueResultData.mutex);
+    while(!m_queueResultData.isEmpty())
+    {
+        auto pData = m_queueResultData.front_pop();
+        if(pData != nullptr)
+        {
+            delete pData;
+            pData = nullptr;
+        }
+    }
+    if(m_result != nullptr)
+    {
+        delete m_result;
+        m_result = nullptr;
+    }
+    /* 清理实时数据 */
+    while(!m_queueRealTimeData.isEmpty())
+    {
+        AudioSrcData* data = m_queueRealTimeData.front_pop();
+        if(data != nullptr)
+        {
+            delete data;
+            data = nullptr;
+        }
+    }
+    m_listRealTimeResult.clear();
+
 }
 
 /* 计算音量和反相 */
@@ -500,8 +522,8 @@ bool CreateDBThread::calculateVolumeData()
     /* 将结果放入结果队列 */
     if(m_result != nullptr)
     {
-        std::lock_guard<std::mutex> lock(m_queueResultData->mutex);
-        auto result = m_queueResultData->push(m_result);
+        std::lock_guard<std::mutex> lock(m_queueResultData.mutex);
+        auto result = m_queueResultData.push(m_result);
         if(result != nullptr)
         {
             // SPDLOG_LOGGER_DEBUG(m_logger, "{} 队列已满,出队一个元素", m_logBase);

+ 1 - 3
Server/ThreadRecord/CreateDBThread.h

@@ -31,8 +31,6 @@ public:
     /* 设置实时数据 */
     bool setRealTimeData(const AudioSrcData& srcData);
 
-    /* 获取结果的环形队列 */
-    RingQueueManualMutex<OneSecondData*>* getResultQueue() { return m_queueResultData; }
     /* 获取最新的结果,根据时间进行对比,最新的时间比传入的晚,就是有新的数据了 */
     bool getLatestResult(OneSecondData& resultData);
     /* 获取最新的结果,让整个环形队列相等 */
@@ -74,7 +72,7 @@ private:
 
     OneSecondData* m_result = nullptr;      /* 存储每秒钟的音量和反相数据 */
     /* 计算结果环形队列,存储每秒钟的音量和反相数据 */
-    RingQueueManualMutex<OneSecondData*>* m_queueResultData = nullptr;
+    RingQueueManualMutex<OneSecondData*> m_queueResultData;
 
     /* --------------------------- 实时音量值的数据 --------------------------- */
     RingQueue<AudioSrcData*> m_queueRealTimeData;   /* 存储小于1秒的音频数据,应该是33m的 */

+ 13 - 0
Server/ThreadRecord/CreateRecordFileThread.cpp

@@ -229,6 +229,8 @@ void CreateRecordFileThread::task()
         writeLongRecordFile();
         
     }
+    
+    clearData();
     SPDLOG_LOGGER_WARN(m_logger, "➢ {} 记录长文件线程结束运行", m_logBase);
 }
 
@@ -266,6 +268,17 @@ void CreateRecordFileThread::clearData()
     /* 清理缓存数据 */
     std::lock_guard<std::mutex> lock(m_mutexBuffer);
     m_bufferData.clear();
+
+    std::lock_guard<std::mutex> lockSrcData(m_ringQueue.mutex);
+    while(!m_ringQueue.isEmpty())
+    {
+        auto data = m_ringQueue.front_pop();
+        if(data != nullptr)
+        {
+            delete data;
+            data = nullptr;
+        }
+    }
 }
 
 

+ 33 - 19
Server/ThreadRecord/CreateWAVThread.cpp

@@ -18,7 +18,7 @@ CreateWAVThread::CreateWAVThread(RecordThreadInfo_t& threadInfo)
     
 CreateWAVThread::~CreateWAVThread()
 {
-
+    clearData();
 }
 
 
@@ -34,8 +34,8 @@ CreateWAVThread::~CreateWAVThread()
  */
 bool CreateWAVThread::setData(const AudioSrcData& srcData)
 {
-    AudioSrcData* newData1 = new AudioSrcData(srcData);
     /* -------------------------- 入队WAV环形队列 ---------------------------- */
+    AudioSrcData* newData1 = new AudioSrcData(srcData);
     if(m_queueWavSrcData.isFull())
     {
         /* 出队一个最早的元素 */
@@ -73,14 +73,14 @@ bool CreateWAVThread::setData(const AudioSrcData& srcData)
 /* 获取最新的数据 */
 bool CreateWAVThread::getLatestFileName(WavFilePath& wavName)
 {
-    if(m_queueWavFileName->isEmpty())
+    if(m_queueWavFileName.isEmpty())
     {
         // SPDLOG_LOGGER_TRACE(m_logger, "{} WAV文件路径队列为空", m_logBase);
         return false;
     }
-    m_queueWavFileName->mutex.lock();
-    wavName = m_queueWavFileName->back();
-    m_queueWavFileName->mutex.unlock();
+    m_queueWavFileName.mutex.lock();
+    wavName = m_queueWavFileName.back();
+    m_queueWavFileName.mutex.unlock();
     return true;
 }
 
@@ -167,7 +167,7 @@ void CreateWAVThread::task()
 /* 初始化数据 */
 bool CreateWAVThread::initData()
 {
-    /* 环形队列大小,默认是3分钟大小 */
+    /* 环形队列大小,默认是2分钟大小 */
     int queueSize = GInfo.queueElementCount();
     m_queueWavSrcData.clearQueue();
     m_queueWavSrcData.setQueueCapacity(queueSize);
@@ -208,9 +208,8 @@ bool CreateWAVThread::initData()
             SPDLOG_LOGGER_INFO(m_logger, "{} 创建WAV目录成功: {}", m_logBase, m_wavDir.path().toStdString());
         }
     }
-    m_filePathNum = 60;
-    m_queueWavFileName = new RingQueueManualMutex<WavFilePath>(m_filePathNum);
-    m_queueLeftRightData.setQueueCapacity(m_filePathNum);
+    m_queueWavFileName.setQueueCapacity(m_filePathNum);
+    m_queueLeftRightData.setQueueCapacity(m_numLeftRight);
 
     m_listDeleteFile.clear();
 
@@ -240,6 +239,21 @@ void CreateWAVThread::clearData()
             data = nullptr;
         }
     }
+
+    /* 删除临时文件夹中的wav小文件 */
+    deleteWAVFile(0); // 删除所有文件
+    m_listDeleteFile.clear();
+
+    std::lock_guard<std::mutex> lock(m_queueLeftRightData.mutex);
+    while(!m_queueLeftRightData.isEmpty())
+    {
+        auto data = m_queueLeftRightData.front_pop();
+        if(data != nullptr)
+        {
+            delete data;
+            data = nullptr;
+        }
+    }
 }
 
 /**
@@ -313,14 +327,14 @@ bool CreateWAVThread::createWAVFile(int secondCount)
     wavFilePath.startDateTime = newFileStartTime;
     wavFilePath.endDateTime = newFileEndTime;
 
-    m_queueWavFileName->mutex.lock();
-    if(m_queueWavFileName->isFull())
+    m_queueWavFileName.mutex.lock();
+    if(m_queueWavFileName.isFull())
     {
-        auto wavFile = m_queueWavFileName->front_pop();
+        auto wavFile = m_queueWavFileName.front_pop();
         m_listDeleteFile.push_back(wavFile);
     }
-    m_queueWavFileName->push(wavFilePath);
-    m_queueWavFileName->mutex.unlock();
+    m_queueWavFileName.push(wavFilePath);
+    m_queueWavFileName.mutex.unlock();
 
     // SPDLOG_LOGGER_DEBUG(m_logger, "{} 数据写入完成,当前队列大小: {}", m_logBase, m_queueWavSrcData.QueueSize());
     // SPDLOG_LOGGER_DEBUG(m_logger, "{} 生成WAV文件成功: {}, 开始时间: {}, 结束时间: {}", 
@@ -397,7 +411,7 @@ bool CreateWAVThread::splitLeftRightChannel()
 
     /* 分离左右声道 / 2,转换成short / 2 */
     bool isStart = true;
-    AudioLeftRightData* pLeftRightData = new AudioLeftRightData(m_noiseElementDuration * m_oneSecondSize / 4);
+    AudioLeftRightData* pLeftRightData = new AudioLeftRightData(m_noiseElementDuration * m_sampleRate);
     for(int32_t i = 0; i < m_noiseElementDuration; ++i)
     {
         AudioSrcData* data = m_queueLeftRightSrcData.front_pop();
@@ -464,9 +478,9 @@ bool CreateWAVThread::splitLeftRightChannel()
         delete tmp; // 删除出队的元素
         tmp = nullptr;
     }
-
-    // SPDLOG_LOGGER_DEBUG(m_logger, "{} 分离左右声道数据完成,左声道数据大小: {}, 右声道数据大小: {}", 
-    //     m_logBase, pLeftRightData->vecLeftData.size(), pLeftRightData->vecRightData.size());
+    int leftSize = pLeftRightData->vecLeftData.size() * sizeof(double) * 2;
+    SPDLOG_LOGGER_DEBUG(m_logger, "{} 队列数据数目: {}, 左声道数据大小: {}, 单个元素大小: {}", 
+        m_logBase, m_queueLeftRightData.QueueSize(), pLeftRightData->vecLeftData.size(), leftSize);
 
     return true;
 }

+ 2 - 7
Server/ThreadRecord/CreateWAVThread.h

@@ -32,9 +32,6 @@ public:
     /* 设置数据 */
     bool setData(const AudioSrcData& srcData) override;
 
-    /* 获取wav小文件路径队列 */
-    RingQueueManualMutex<WavFilePath>* getQueueWavFilePath() { return m_queueWavFileName; }
-
     /* 获取最新的数据 */
     bool getLatestFileName(WavFilePath& wavName);
     /* 获取最新的左右声道数据 */
@@ -67,15 +64,13 @@ private:
     
     std::list<WavFilePath> m_listDeleteFile;        /* 将要删除的文件名列表 */
 
-    // std::string m_newFileName;                      /* 新文件名 */
-    // QDateTime m_newFileStartTime;                   /* 新文件开始时间 */
-    // QDateTime m_newFileEndTime;                     /* 新文件结束时间 */
     int m_filePathNum = 60;                         /* wav小文件路径队列的容量,默认60个文件 */
     /* wav小文件路径队列,这个队列只给一致性检测线程用
      * 注意:这个队列可能会给多个一致性线程检测使用,队列中的元素由本线程管理删除,
       * 其他线程只能copy出去 */
-    RingQueueManualMutex<WavFilePath>* m_queueWavFileName = nullptr;
+    RingQueueManualMutex<WavFilePath> m_queueWavFileName;
     RingQueueManualMutex<AudioLeftRightData*> m_queueLeftRightData; /* 左右声道数据的环形队列 */
+    int m_numLeftRight = 10;                        /* 这个队列占用内存非常多,因此设置数目小一些 */
 };
 
 

+ 47 - 20
Server/ThreadRecord/RecordThread.cpp

@@ -21,22 +21,22 @@ RecordThread::~RecordThread()
 
 
 /* 设置声卡描述符 */
-void RecordThread::setAudioRecordDesc(const std::string& desc)
-{
-    m_audioRecordDesc = desc;
-}
+// void RecordThread::setAudioRecordDesc(const std::string& desc)
+// {
+//     m_audioRecordDesc = desc;
+// }
 
 /* 设置分派线程的指针 */
-void RecordThread::setAssignSrcDataThread(AssignSrcDataThread* pThread)
-{
-    if(pThread == nullptr)
-    {
-        SPDLOG_LOGGER_ERROR(m_logger, "{} 分派数据线程指针为空", m_logBase);
-        return;
-    }
-    m_assignThread = pThread;
-    // SPDLOG_LOGGER_INFO(m_logger, "{} 设置分派数据线程成功", m_logBase);
-}
+// void RecordThread::setAssignSrcDataThread(AssignSrcDataThread* pThread)
+// {
+//     if(pThread == nullptr)
+//     {
+//         SPDLOG_LOGGER_ERROR(m_logger, "{} 分派数据线程指针为空", m_logBase);
+//         return;
+//     }
+//     m_assignThread = pThread;
+//     // SPDLOG_LOGGER_INFO(m_logger, "{} 设置分派数据线程成功", m_logBase);
+// }
 
 /* 录制功能线程函数 */
 void RecordThread::task()
@@ -59,6 +59,8 @@ void RecordThread::task()
         SPDLOG_LOGGER_ERROR(m_logger, "{} 声卡描述符为空,无法打开录音通道", m_logBase);
         return;
     }
+    /* 初始化录制类的参数 */
+    m_audioRecord.setRecordParams(m_sampleRate, m_bitsPerSample, m_numChannels);
     if(!m_audioRecord.openRecordChannel(m_audioRecordDesc))
     {
         SPDLOG_LOGGER_ERROR(m_logger, "{} 打开声卡通道失败: {}", m_logBase, m_audioRecordDesc);
@@ -66,7 +68,7 @@ void RecordThread::task()
     }
 #endif /* RECORD_READFILE */
 
-
+    /* 获取分派数据线程 */
     while(m_assignThread == nullptr)
     {
         std::this_thread::sleep_for(std::chrono::milliseconds(100));
@@ -149,12 +151,9 @@ bool RecordThread::initData()
     m_oneRecordCount = m_sampleRate / VOLUME_INFO_NUM;
     m_pRecordBuffer = new char[m_recordBufferSize] {0};  /* 录音数据缓存 */
 
-    /* 初始化录制类的参数 */
-    m_audioRecord.setRecordParams(m_sampleRate, m_bitsPerSample, m_numChannels);
 
-    /* 设置声卡描述符 */
-    // m_audioRecordDesc = fmt::format("hw:{},{}", m_threadInfo.cardRoadInfo.nSoundCardNum, m_threadInfo.cardRoadInfo.roadInfo.nRoadNum);
-    m_audioRecordDesc = m_threadInfo.cardRoadInfo.pcmInfo.strPCMName;
+    /* 处理声卡名称 */
+    m_audioRecordDesc = processPCMName(m_threadInfo.cardRoadInfo.pcmInfo.strPCMName);
 
 
     return true;
@@ -171,6 +170,34 @@ void RecordThread::clearData()
     m_recordBufferSize = 0;
 }
 
+/* 处理声卡名称,对PCM通道名称进行处理,有些需要添加“plug”,有些需要添加“plug:” */
+std::string RecordThread::processPCMName(std::string srcPCMName)
+{
+    std::string pcmName;
+    /* 查找名称开头中是否包含plug */
+    if("plughw:" == srcPCMName.substr(0, 7))
+    {
+        /* 如果包含plug,则直接使用 */
+        pcmName = srcPCMName;
+    } 
+    else if("hw:" == srcPCMName.substr(0, 3))
+    {
+        /* 否则,添加plug前缀 */
+        pcmName = fmt::format("plug{}", srcPCMName);
+    }
+    else if("mic" == srcPCMName.substr(0, 3))
+    {
+        /* alpdaten声卡的通道 */
+        pcmName = fmt::format("plug:{}", srcPCMName);
+    }
+    else {
+        /* 其他情况直接使用 */
+        pcmName = srcPCMName;
+    }
+
+    return pcmName;
+}
+
 
 /* 获取AssignSrcDataThread线程 */
 AssignSrcDataThread* RecordThread::getAssignSrcDataThread()

+ 5 - 2
Server/ThreadRecord/RecordThread.h

@@ -33,9 +33,9 @@ public:
 
 
     /* 设置声卡描述符 */
-    void setAudioRecordDesc(const std::string& desc);
+    // void setAudioRecordDesc(const std::string& desc);
     /* 设置分派线程的指针 */
-    void setAssignSrcDataThread(AssignSrcDataThread* pThread);
+    // void setAssignSrcDataThread(AssignSrcDataThread* pThread);
     
 
 private:
@@ -49,6 +49,9 @@ private:
     /* 清除数据 */
     void clearData() override;
 
+    /* 处理声卡名称 */
+    std::string processPCMName(std::string srcPCMName);
+
     /* 获取AssignSrcDataThread线程 */
     AssignSrcDataThread* getAssignSrcDataThread();
 

+ 1 - 1
common/GlobalInfo/GlobalVariable.h

@@ -18,7 +18,7 @@
 
 /* 声卡识别符号,在PCM通道中通过这个字符识别是属于哪些声卡的 */
 
-#define SC_System   "SystemOther"       /* 不需要识别的声卡 */
+#define SC_System   "SystemDefault"       /* 不需要识别的声卡 */
 #define SC_AlpDANTE "AlpDANTE"          /* dante声卡 */
 
 

+ 1 - 0
文档/保存的命令.txt

@@ -0,0 +1 @@
+scp ACAServer TEST@192.1.2.129:~/Desktop