Browse Source

V0.2.2
1、给录音线程添加了锁

Apple 2 weeks ago
parent
commit
da61166a85

+ 1 - 1
Server/ThreadCalculate/CalculateDBThread.cpp

@@ -113,7 +113,7 @@ bool CalculateDBThread::initData()
     m_roadInfo = begin.value(); // 获取第一个通道的信息
     m_roadName = m_roadInfo.strCompareRoadName.toStdString();
 
-    m_threadCreateDBPhase = ThreadMan.getCreateDBPhaseThread(m_roadInfo.scRoadInfo.nSoundCardNum, m_roadInfo.scRoadInfo.roadInfo.nRoadNum);
+    m_threadCreateDBPhase = ThreadMan.getCreateDBThread(m_roadInfo.scRoadInfo.nSoundCardNum, m_roadInfo.scRoadInfo.roadInfo.nRoadNum);
     if (m_threadCreateDBPhase == nullptr)
     {
         SPDLOG_LOGGER_ERROR(m_logger, "{} 获取创建音量线程失败", m_logBase);

+ 2 - 2
Server/ThreadCalculate/CalculateDBThread.h

@@ -3,7 +3,7 @@
 
 #include "AudioData.h"
 #include "BaseCalculateThread.h"
-#include "CreateDBPhaseThread.h"
+#include "CreateDBThread.h"
 #include "SendStruct.h"
 #include "CalculateAudio.h"
 #include "AlarmInfo.h"
@@ -70,7 +70,7 @@ private:
     OneRoadVolume_t m_roadVolumeInfo;                       /* 一个录音通道的音量信息这个是计算结果 */
 
     /* 生成音量的线程 */
-    CreateDBPhaseThread* m_threadCreateDBPhase = nullptr;   /* 生成音量的线程 */
+    CreateDBThread* m_threadCreateDBPhase = nullptr;   /* 生成音量的线程 */
     OneSecondData m_currSecondData;                         /* 最新一秒的数据 */
     StVolumeParam m_volumeParam;                            /* 音量计算的参数 */
 

+ 2 - 2
Server/ThreadCalculate/CompareDoubleThread.cpp

@@ -112,8 +112,8 @@ bool CompareDoubleThread::initData()
     m_nIsSameBothMinDBWaitNum = GInfo.nIsSameBothMinDBWaitNum(); // 获取是否需要等待静音状态
 
     /* 获取生成音量的线程 */
-    m_threadCreateDBPhase1 = ThreadMan.getCreateDBPhaseThread(m_roadInfo1.nSoundCardNum, m_roadInfo1.roadInfo.nRoadNum);
-    m_threadCreateDBPhase2 = ThreadMan.getCreateDBPhaseThread(m_roadInfo2.nSoundCardNum, m_roadInfo2.roadInfo.nRoadNum);
+    m_threadCreateDBPhase1 = ThreadMan.getCreateDBThread(m_roadInfo1.nSoundCardNum, m_roadInfo1.roadInfo.nRoadNum);
+    m_threadCreateDBPhase2 = ThreadMan.getCreateDBThread(m_roadInfo2.nSoundCardNum, m_roadInfo2.roadInfo.nRoadNum);
     if(m_threadCreateDBPhase1 == nullptr || m_threadCreateDBPhase2 == nullptr)
     {
         SPDLOG_LOGGER_ERROR(m_logger, "{} 获取生成音量的线程失败", m_logBase);

+ 3 - 3
Server/ThreadCalculate/CompareDoubleThread.h

@@ -4,7 +4,7 @@
 #include "AudioData.h"
 #include "ChannelParam.h"
 #include "CompareResult.h"
-#include "CreateDBPhaseThread.h"
+#include "CreateDBThread.h"
 #include "SendStruct.h"
 #include "ConsistencyResult.h"
 #include "CalculateAudio.h"
@@ -92,8 +92,8 @@ private:
     SoundCardRoadInfo_t m_roadInfo2;                        /* 录音通道2信息 */
 
     /* 生成音量数据的线程 */
-    CreateDBPhaseThread* m_threadCreateDBPhase1 = nullptr;  /* 生成通道1音量数据的线程 */
-    CreateDBPhaseThread* m_threadCreateDBPhase2 = nullptr;  /* 生成通道2音量数据的线程 */
+    CreateDBThread* m_threadCreateDBPhase1 = nullptr;  /* 生成通道1音量数据的线程 */
+    CreateDBThread* m_threadCreateDBPhase2 = nullptr;  /* 生成通道2音量数据的线程 */
     bool m_isUpdated1 = false;                              /* 通道1数据是否更新 */
     bool m_isUpdated2 = false;                              /* 通道2数据是否更新 */
     /* 本地存储音量数据的环形队列 */

+ 72 - 32
Server/ThreadManager/ThreadManager.cpp

@@ -1,7 +1,7 @@
 #include "ThreadManager.h"
 
 #include "CreateWAVThread.h"
-#include "CreateDBPhaseThread.h"
+#include "CreateDBThread.h"
 
 #include "CalculateDBThread.h"
 #include "ConsistencyCompareThread.h"
@@ -10,6 +10,7 @@
 #include "RtpOneRoadThread.h"
 
 #include "ThreadPool.h"
+#include <mutex>
 
 ThreadManager::ThreadManager()
 {
@@ -34,11 +35,28 @@ void ThreadManager::stopAllThreads()
 
 }
 
-// /* 添加线程 */
-// void ThreadManager::addThread(StRecordThreadInfo* pThreadInfo)
-// {
+/* 创建一个录音通道及其附属的线程 */
+bool ThreadManager::createRecordThread(const SoundCardRoadInfo_t& roadInfo)
+{
+    /* 需要修改的地方
+        1、录音线程修改线程函数,添加task()函数,统一处理开启和关闭状态
+        2、原始录音线程,获取分派数据的函数指针不再自己获取,而是由分派线程自己设置过来指针
+        3、给存储录音线程的队列添加互斥锁,保护线程的创建和销毁
+     */
+    
+    /* 先查找队列中有没有该录音通道 */
+
+    return true;
+}
+
+/* 销毁一个录音通道及其附属的线程 */
+bool ThreadManager::destroyRecordThread(const SoundCardRoadInfo_t& roadInfo)
+{
+
+    return true;
+}
+
 
-// }
 
 /* 查找录音线程 */
 BaseRecordThread* ThreadManager::findRecordThread(EThreadType type, int cardID, int recordID)
@@ -46,61 +64,80 @@ BaseRecordThread* ThreadManager::findRecordThread(EThreadType type, int cardID,
     switch(type)
     {
         case EThreadType::Type_RecordSrc:           /* 录音线程 */
-            for (auto& pThread : m_recordThreads)
             {
-                if (pThread->getThreadInfo().cardRoadInfo.roadInfo.nRoadNum == recordID &&
-                    pThread->getThreadInfo().cardRoadInfo.nSoundCardNum == cardID)
+                std::lock_guard<std::mutex> lock(m_mutexRecordThreads);
+                for (auto& pThread : m_recordThreads)
                 {
-                    return pThread;
+                    if (pThread->getThreadInfo().cardRoadInfo.roadInfo.nRoadNum == recordID &&
+                        pThread->getThreadInfo().cardRoadInfo.nSoundCardNum == cardID)
+                    {
+                        return pThread;
+                    }
                 }
             }
             break;
         case EThreadType::Type_CreateWAV:           /* 创建wav小文件和分离左右声道的线程 */
-            for (auto& pThread : m_createWAVThreads)
             {
-                if (pThread->getThreadInfo().cardRoadInfo.nSoundCardNum == cardID &&
-                    pThread->getThreadInfo().cardRoadInfo.roadInfo.nRoadNum == recordID)
+                std::lock_guard<std::mutex> lock(m_mutexCreateWAVThreads);
+                for (auto& pThread : m_createWAVThreads)
                 {
-                    return pThread;
+                    if (pThread->getThreadInfo().cardRoadInfo.nSoundCardNum == cardID &&
+                        pThread->getThreadInfo().cardRoadInfo.roadInfo.nRoadNum == recordID)
+                    {
+                        return pThread;
+                    }
                 }
             }
             break;
         case EThreadType::Type_CalculateDBAndPhase:      /* 计算音量和反相的线程 */
-            for (auto& pThread : m_createDBPhaseThreads)
             {
-                if (pThread->getThreadInfo().cardRoadInfo.nSoundCardNum == cardID &&
-                    pThread->getThreadInfo().cardRoadInfo.roadInfo.nRoadNum == recordID)
+                std::lock_guard<std::mutex> lock(m_mutexCreateDBThreads);
+                for (auto& pThread : m_createDBThreads)
                 {
-                    return pThread;
+                    if (pThread->getThreadInfo().cardRoadInfo.nSoundCardNum == cardID &&
+                        pThread->getThreadInfo().cardRoadInfo.roadInfo.nRoadNum == recordID)
+                    {
+                        return pThread;
+                    }
                 }
             }
             break;
         case EThreadType::Type_CreateLongWAV:           /* 创建长文件的线程 */
-            for (auto& pThread : m_createLongWAVThreads)
             {
-                if (pThread->getThreadInfo().cardRoadInfo.nSoundCardNum == cardID &&
-                    pThread->getThreadInfo().cardRoadInfo.roadInfo.nRoadNum == recordID)
+                std::lock_guard<std::mutex> lock(m_mutexCreateLongWAVThreads);
+                for (auto& pThread : m_createLongWAVThreads)
                 {
-                    return pThread;
+                    if (pThread->getThreadInfo().cardRoadInfo.nSoundCardNum == cardID &&
+                        pThread->getThreadInfo().cardRoadInfo.roadInfo.nRoadNum == recordID)
+                    {
+                        return pThread;
+                    }
                 }
             }
             break;
         case EThreadType::Type_AssignSrcData:           /* 分派数据线程 */
-            for (auto& pThread : m_assignSrcDataThreads)
             {
-                if (pThread->getThreadInfo().cardRoadInfo.nSoundCardNum == cardID &&
-                    pThread->getThreadInfo().cardRoadInfo.roadInfo.nRoadNum == recordID)
+                std::lock_guard<std::mutex> lock(m_mutexAssignSrcDataThreads);
+                for (auto& pThread : m_assignSrcDataThreads)
                 {
-                    return pThread;
+                    if (pThread->getThreadInfo().cardRoadInfo.nSoundCardNum == cardID &&
+                        pThread->getThreadInfo().cardRoadInfo.roadInfo.nRoadNum == recordID)
+                    {
+                        return pThread;
+                    }
                 }
             }
+            break;
         case EThreadType::Type_RtpSend:               /* RTP发送线程 */
-            for (auto& pThread : m_rtpSendThreads)
             {
-                if (pThread->getThreadInfo().cardRoadInfo.nSoundCardNum == cardID &&
-                    pThread->getThreadInfo().cardRoadInfo.roadInfo.nRoadNum == recordID)
+                std::lock_guard<std::mutex> lock(m_mutexRtpSendThreads);
+                for (auto& pThread : m_rtpSendThreads)
                 {
-                    return pThread;
+                    if (pThread->getThreadInfo().cardRoadInfo.nSoundCardNum == cardID &&
+                        pThread->getThreadInfo().cardRoadInfo.roadInfo.nRoadNum == recordID)
+                    {
+                        return pThread;
+                    }
                 }
             }
             break;
@@ -117,6 +154,7 @@ BaseRecordThread* ThreadManager::findRecordThread(EThreadType type, int cardID,
 /* 获取创建WAV线程指针 */
 CreateWAVThread* ThreadManager::getCreateWAVThread(int cardID, int recordID)
 {
+    std::lock_guard<std::mutex> lock(m_mutexCreateWAVThreads);
     for(auto& pThread : m_createWAVThreads)
     {
         if(pThread->getThreadInfo().cardRoadInfo.nSoundCardNum == cardID &&
@@ -129,14 +167,15 @@ CreateWAVThread* ThreadManager::getCreateWAVThread(int cardID, int recordID)
 }
 
 /* 获取创建音量值的线程 */
-CreateDBPhaseThread* ThreadManager::getCreateDBPhaseThread(int cardID, int recordID)
+CreateDBThread* ThreadManager::getCreateDBThread(int cardID, int recordID)
 {
-    for(auto& pThread : m_createDBPhaseThreads)
+    std::lock_guard<std::mutex> lock(m_mutexCreateDBThreads);
+    for(auto& pThread : m_createDBThreads)
     {
         if(pThread->getThreadInfo().cardRoadInfo.nSoundCardNum == cardID &&
            pThread->getThreadInfo().cardRoadInfo.roadInfo.nRoadNum == recordID)
         {
-            return dynamic_cast<CreateDBPhaseThread*>(pThread);
+            return dynamic_cast<CreateDBThread*>(pThread);
         }
     }
     return nullptr;
@@ -145,6 +184,7 @@ CreateDBPhaseThread* ThreadManager::getCreateDBPhaseThread(int cardID, int recor
 /* 获取发送Rtp数据的线程 */
 RTPOneRoadThread* ThreadManager::getRtpSendThread(int cardID, int recordID)
 {
+    std::lock_guard<std::mutex> lock(m_mutexRtpSendThreads);
     for(auto& pThread : m_rtpSendThreads)
     {
         if(pThread->getThreadInfo().cardRoadInfo.nSoundCardNum == cardID &&

+ 27 - 9
Server/ThreadManager/ThreadManager.h

@@ -3,19 +3,18 @@
 
 #include "spdlog/spdlog.h"
 #include "BaseRecordThread.h"
-#include "CreateDBPhaseThread.h"
+#include "CreateDBThread.h"
 #include "GlobalVariable.h"
 #include "AudioData.h"
 #include "RingQueue.hpp"
 #include "RingQueueManualMutex.hpp"
 
 #include <list>
+#include <mutex>
 
 class CreateWAVThread;
-class CalculateDBAndPhase;
 class ConsistencyCompareThread;
 class NoiseDetectThread;
-class CalculateDBPhaseThread;
 class RTPOneRoadThread;
 
 
@@ -44,19 +43,29 @@ public:
     /* 停止所有线程 */
     void stopAllThreads();
 
-    /* 添加线程 */
-    // void addThread(StRecordThreadInfo* pThreadInfo);
+    /* -------------------------------------------------------------------------------------------
+     * 创建录音线程,传入声卡编号和录音通道编号
+     * 录音线程是统一创建的,有一路录音通道,就会有所有的对应的原始音频处理线程
+     * 创建的时候需要传入对比项ID,这里会记录对比项ID,作为该录音通道的引用计数,该对比项销毁的时候需要调用
+     * 销毁该录音线程的函数,这样引用计数就会减1,直到引用计数为0时,会销毁该线程
+     * -------------------------------------------------------------------------------------------- */
+    /* 创建一个录音通道及其附属的线程 */
+    bool createRecordThread(const SoundCardRoadInfo_t& roadInfo);
+    /* 销毁一个录音通道及其附属的线程 */
+    bool destroyRecordThread(const SoundCardRoadInfo_t& roadInfo);
 
-    /* 查找录音线程 */
-    BaseRecordThread* findRecordThread(EThreadType type, int cardID, int recordID);
 
     /* -------------------------------------------------------------------------------------------
      * 获取录音线程,录音线程是统一创建的,有一路录音通道,就会有所有的对应的录音处理线程
      * -------------------------------------------------------------------------------------------- */
+    /* 查找录音线程,给原始音频分派数据的线程使用的 */
+    BaseRecordThread* findRecordThread(EThreadType type, int cardID, int recordID);
+    
+    /* 这三个线程给对比项以及其附属的计算线程使用的 */
     /* 获取创建WAV线程指针 */
     CreateWAVThread* getCreateWAVThread(int cardID, int recordID);
     /* 获取创建音量值的线程 */
-    CreateDBPhaseThread* getCreateDBPhaseThread(int cardID, int recordID);
+    CreateDBThread* getCreateDBThread(int cardID, int recordID);
     /* 获取发送Rtp数据的线程 */
     RTPOneRoadThread* getRtpSendThread(int cardID, int recordID);
 
@@ -83,17 +92,26 @@ public:
     // bool removeCalculateDBPhaseThread(SoundCardRoadInfo_t& roadInfo);
 
 private:
+    /* 记录每个录音通道的引用计数 */
+    std::map<SoundCardRoadInfo_t, int> m_recordThreadRefCount;
+
     /* 录音线程队列 */
+    std::mutex m_mutexRecordThreads;
     std::list<BaseRecordThread*> m_recordThreads;
     /* 分派数据线程队列 */
+    std::mutex m_mutexAssignSrcDataThreads;
     std::list<BaseRecordThread*> m_assignSrcDataThreads;
     /* 生成wav小文件线程队列 */
+    std::mutex m_mutexCreateWAVThreads;
     std::list<BaseRecordThread*> m_createWAVThreads;
     /* 计算音量和反相线程队列 */
-    std::list<BaseRecordThread*> m_createDBPhaseThreads;
+    std::mutex m_mutexCreateDBThreads;
+    std::list<BaseRecordThread*> m_createDBThreads;
     /* 生成长文件线程队列 */
+    std::mutex m_mutexCreateLongWAVThreads;
     std::list<BaseRecordThread*> m_createLongWAVThreads;
     /* 发送Rtp数据的线程 */
+    std::mutex m_mutexRtpSendThreads;
     std::list<BaseRecordThread*> m_rtpSendThreads;
 
     /* 一致性比对的线程 */

+ 10 - 10
Server/ThreadRecord/CreateDBPhaseThread.cpp → Server/ThreadRecord/CreateDBThread.cpp

@@ -1,4 +1,4 @@
-#include "CreateDBPhaseThread.h"
+#include "CreateDBThread.h"
 
 #include "GlobalVariable.h"
 #include "AudioData.h"
@@ -6,19 +6,19 @@
 
 #include "CalculateAudio.h"
 
-CreateDBPhaseThread::CreateDBPhaseThread(RecordThreadInfo_t& threadInfo)
+CreateDBThread::CreateDBThread(RecordThreadInfo_t& threadInfo)
     : BaseRecordThread(threadInfo)
 {
 
 }
 
-CreateDBPhaseThread::~CreateDBPhaseThread()
+CreateDBThread::~CreateDBThread()
 {
 
 }
 
 /* 计算音量和反相的线程函数 */
-void CreateDBPhaseThread::threadTask()
+void CreateDBThread::threadTask()
 {
     SPDLOG_LOGGER_INFO(m_logger, "{} 开始计算音量和反相线程", m_logBase);
     /* 初始化一些数据 */
@@ -68,7 +68,7 @@ void CreateDBPhaseThread::threadTask()
 }
 
 /* 设置数据 */
-bool CreateDBPhaseThread::setData(const AudioSrcData& srcData)
+bool CreateDBThread::setData(const AudioSrcData& srcData)
 {
     if(srcData.pData == nullptr || srcData.dataSize == 0)
     {
@@ -108,7 +108,7 @@ bool CreateDBPhaseThread::setData(const AudioSrcData& srcData)
 
 
 /* 获取最新的结果,根据时间进行对比,最新的时间比传入的晚,就是有新的数据了 */
-bool CreateDBPhaseThread::getLatestResult(OneSecondData& resultData)
+bool CreateDBThread::getLatestResult(OneSecondData& resultData)
 {
     if(resultData.startTime.isNull())
     {
@@ -132,7 +132,7 @@ bool CreateDBPhaseThread::getLatestResult(OneSecondData& resultData)
 }
 
 /* 获取最新的结果,让整个环形队列相等 */
-bool CreateDBPhaseThread::getLatestResult(RingQueueManualMutex<OneSecondData*>& resultQueue)
+bool CreateDBThread::getLatestResult(RingQueueManualMutex<OneSecondData*>& resultQueue)
 {
     std::lock_guard<std::mutex> lock(m_queueResultData->mutex);
     if(m_queueResultData->isEmpty())
@@ -200,7 +200,7 @@ bool CreateDBPhaseThread::getLatestResult(RingQueueManualMutex<OneSecondData*>&
 }
 
 /* 初始化一些数据 */
-bool CreateDBPhaseThread::initData()
+bool CreateDBThread::initData()
 {
     /* 初始化一些数据 */
     m_queueAudioData.clearQueue();
@@ -223,7 +223,7 @@ bool CreateDBPhaseThread::initData()
 }
 
 /* 清理数据 */
-void CreateDBPhaseThread::clearData()
+void CreateDBThread::clearData()
 {
     /* 清理环形队列 */
     while(!m_queueAudioData.isEmpty())
@@ -243,7 +243,7 @@ void CreateDBPhaseThread::clearData()
 }
 
 /* 计算音量和反相 */
-bool CreateDBPhaseThread::CreateDBPhase(AudioSrcData* audioData, OneSecondData* resultData)
+bool CreateDBThread::CreateDBPhase(AudioSrcData* audioData, OneSecondData* resultData)
 {
     short* pWaveVu = (short*)(audioData->pData);
 

+ 6 - 6
Server/ThreadRecord/CreateDBPhaseThread.h → Server/ThreadRecord/CreateDBThread.h

@@ -1,5 +1,5 @@
-#ifndef _CREATEDBPHASETHREAD_H_
-#define _CREATEDBPHASETHREAD_H_
+#ifndef _CREATEDBTHREAD_H_
+#define _CREATEDBTHREAD_H_
 
 
 #include "BaseRecordThread.h"
@@ -15,12 +15,12 @@ class OneSecondData;
  * 
  */
 
-class CreateDBPhaseThread : public BaseRecordThread
+class CreateDBThread : public BaseRecordThread
 {
 
 public:
-    CreateDBPhaseThread(RecordThreadInfo_t& threadInfo);
-    ~CreateDBPhaseThread() override;
+    CreateDBThread(RecordThreadInfo_t& threadInfo);
+    ~CreateDBThread() override;
 
     /* 计算音量和反相的线程函数 */
     void threadTask() override;
@@ -61,4 +61,4 @@ private:
 };
 
 
-#endif // _CREATEDBPHASETHREAD_H_
+#endif // _CREATEDBTHREAD_H_