123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412 |
- #include "ThreadCompareItemManager.h"
- #include "GlobalInfo.h"
- #include "SystemConfig.h"
- #include "CompareItemThread.h"
- #include "ThreadPool.h"
- #include "OneThread.h"
- /* 给对比项套一层壳,这个函数就是新的线程,在里面new出新的对比项实例,防止Qt报线程归属权错误
- 在函数中将对比项实例插入到线程管理器中 */
- void ThreadCompareItemManager::thread_compareItem(CalculateThreadInfo_t threadInfo)
- {
- auto pThread = new CompareItemThread(threadInfo);
- if(pThread == nullptr)
- {
- SPDLOG_ERROR("ThreadCompareItemManager: 创建对比项线程失败");
- return;
- }
- CompareItemManager.addCompareItemThread(pThread);
-
- /* 启动线程,就会一直阻塞在这里了 */
- pThread->threadTask();
- }
- ThreadCompareItemManager::ThreadCompareItemManager()
- {
-
-
-
- }
- ThreadCompareItemManager::~ThreadCompareItemManager()
- {
- }
- /* 线程函数 */
- void ThreadCompareItemManager::thread_CompareItemManager()
- {
- m_logger = spdlog::get("CompareItemManager");
- if(m_logger == nullptr)
- {
- fmt::print("ThreadCompareItemManager: CompareItemManager Logger not found.\n");
- return;
- }
-
- /* 初始化webapi */
- m_webAPIUrl = GInfo.webAPIUrl();
- m_webAPIID = GInfo.webAPIID();
- m_webAPIAppType = GInfo.webApiAppType();
- if(!m_fromWebAPI.initWebApi(m_webAPIUrl, m_webAPIID, m_webAPIAppType))
- {
- SPDLOG_LOGGER_ERROR(m_logger, "ThreadCompareItemManager: 初始化WebAPI失败");
- return;
- }
- /* 创建一些变量 */
- int threadSleepTime = 2; // 线程休眠时间,单位秒
- /* 获取基础配置,目前只获取一次 */
- updateBaseSettings();
- SPDLOG_LOGGER_INFO(m_logger, "开启对比项管理线程");
- while(true)
- {
- std::this_thread::sleep_for(std::chrono::seconds(threadSleepTime));
- if(threadSleepTime < 10)
- {
- /* 线程睡眠时间恢复为10秒 */
- threadSleepTime = 10;
- }
- /* ------------------------------------------------------------------
- * 处理对比项信息
- * ------------------------------------------------------------------ */
- processCompareItemInfo();
-
- /* ------------------------------ 更新检测时段 ------------------------------ */
- }
- SPDLOG_LOGGER_INFO(m_logger, "ThreadCompareItemManager: 线程结束");
- }
- /* 添加对比项实例 */
- 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获取声卡通道信息 */
- SoundCardRoadInfo_t ThreadCompareItemManager::getSoundCardRoadInfo(int compareItemID, int roadNum)
- {
- std::lock_guard<std::mutex> lock(m_mutexCompareItemThreads);
- auto it = m_mapThreads.find(compareItemID);
- if(it == m_mapThreads.end())
- {
- SPDLOG_LOGGER_WARN(m_logger, "对比项线程不存在,ID: {}", compareItemID);
- return SoundCardRoadInfo_t();
- }
- auto compareInfo = it.value()->getThreadInfo().compareItemInfo;
- SoundCardRoadInfo_t roadInfo;
- for(const auto& road : compareInfo.mapRoad)
- {
- if(road.nCompareRoadNum == roadNum)
- {
- roadInfo = road.scRoadInfo;
- break;
- }
- }
- return roadInfo;
- }
- /* 更新基础设置信息,如数据库设置,噪音参数等 */
- bool ThreadCompareItemManager::updateBaseSettings()
- {
- /* 更新基础数据 */
- QMap<std::string, std::string> baseSettings;
- if(!m_fromWebAPI.getSystemConfig(baseSettings))
- {
- SPDLOG_LOGGER_ERROR(m_logger, "获取系统配置失败");
- return false;
- }
- /* 将获取到的配置转换成结构体 */
- SysConfig.parseConfigFromDatabase(baseSettings);
- /* 检测时段单独获取 */
- QMap<int, DetectPeriodConfig_t> mapDetectConfig;
- if(!m_fromWebAPI.getDetectPeriodConfig(mapDetectConfig))
- {
- SPDLOG_ERROR("获取对比项检测时段配置失败");
- return false;
- }
- SysConfig.setDetectPeriodConfig(mapDetectConfig);
- return true;
- }
- /* 对比项信息处理函数 */
- void ThreadCompareItemManager::processCompareItemInfo()
- {
- /* 获取对比项信息 */
- if(!m_fromWebAPI.getCompareItemInfo(m_listNewItems))
- {
- SPDLOG_LOGGER_DEBUG(m_logger, "ThreadCompareItemManager: 获取对比项失败");
- return;;
- }
-
- checkCompareItemInfo(m_listCreateItems, m_listUpdateItems, m_listDeleteItems);
- SPDLOG_LOGGER_DEBUG(m_logger, "要退出的对比项个数: {}, 要更新的对比项个数: {}, 要创建的对比项个数: {}",
- m_listDeleteItems.size(), m_listUpdateItems.size(), m_listCreateItems.size());
- /* 先删除已消失的对比项信息 */
- processDeleteCompareItemThreads(m_listDeleteItems);
- /* 更新需要更新的线程 */
- updateRunningThreads(m_listUpdateItems);
- /* 再创建新的对比项线程 */
- createNewCompareItemThreads(m_listCreateItems);
- }
- /**
- * @brief 处理对比项信息,新获取的和已有的对比
- *
- * @param createList 创建列表
- * @param updateList 更新列表,根据对比项ID进行更新信息
- * @param deleteList 删除列表
- */
- void ThreadCompareItemManager::checkCompareItemInfo(QList<CompareItemInfo_t>& createList, QList<CompareItemInfo_t>& updateList, QList<int>& deleteList)
- {
- createList.clear();
- updateList.clear();
- deleteList.clear();
- QMap<int, CompareItemInfo_t> mapNowItems;
- /* 先从对比项线程中获取对比项信息 */
- for(auto it = m_mapThreads.begin(); it != m_mapThreads.end(); ++it)
- {
- BaseCalculateThread* pThread = it.value();
- if(pThread == nullptr)
- {
- continue;
- }
-
- /* 获取对比项信息 */
- CompareItemInfo_t itemInfo = pThread->getThreadInfo().compareItemInfo;
- mapNowItems.insert(itemInfo.nID, itemInfo);
- }
- /* 遍历新获取的对比项信息,找出需要新增的对比项和需要更新的对比项 */
- for(const CompareItemInfo_t& item : m_listNewItems)
- {
- if(!mapNowItems.contains(item.nID))
- {
- /* 新对比项,添加到创建列表 */
- createList.append(item);
- } else
- {
- /* 已有对比项,检查是否需要更新 */
- const CompareItemInfo_t& existingItem = mapNowItems.value(item.nID);
- /* 先对比基础信息 */
- if(!existingItem.isEqualBase(item))
- {
- /* 基础信息不同,需要更新 */
- updateList.append(item);
- continue;
- }
- /* 在对比对比项通道信息 */
- if(!existingItem.isEqualRoads(item))
- {
- /* 通道信息不同,需要更新 */
- updateList.append(item);
- continue;
- }
- }
- }
- /* 遍历当前对比项信息,找出需要删除的对比项 */
- for(auto it : mapNowItems)
- {
- bool isFound = false;
- for(const CompareItemInfo_t& newItem : m_listNewItems)
- {
- if(it.nID == newItem.nID)
- {
- isFound = true;
- break; // 找到对应的对比项,不需要删除
- }
- }
- if(!isFound)
- {
- /* 当前对比项不在新获取的对比项中,说明需要删除 */
- deleteList.append(it.nID);
- }
-
- }
- }
- /**
- * @brief 处理需要删除的对比项线程
- * 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();
- if(pThread == nullptr)
- {
- SPDLOG_LOGGER_WARN(m_logger, "对比项线程指针为空,即将删除该线程指针");
- it = m_mapThreads.erase(it);
- continue;
- }
- if(pThread->getThreadInfo().threadState == EThreadState::State_Stopped)
- {
- /* 线程已经停止,直接删除 */
- SPDLOG_LOGGER_INFO(m_logger, "对比项线程 {} 已经停止,准备删除", pThread->getThreadInfo().compareItemInfo.strName.toStdString());
- delete pThread;
- it = m_mapThreads.erase(it);
- continue;
- }
- ++it;
- }
- /* 停止本次需要停止的线程 */
- for(auto it : m_mapThreads)
- {
- int compareItemID = it->getThreadInfo().compareItemInfo.nID;
- if(deleteList.contains(compareItemID))
- {
- /* 设置线程停止标志 */
- it->stopThread();
- SPDLOG_LOGGER_INFO(m_logger, "对比项线程 {} 设置为停止状态", it->getThreadInfo().compareItemInfo.strName.toStdString());
- }
- }
- }
- /* 更新正在运行的线程信息 */
- void ThreadCompareItemManager::updateRunningThreads(const QList<CompareItemInfo_t>& updateList)
- {
- if(updateList.isEmpty())
- {
- return;
- }
- for(const CompareItemInfo_t& item : updateList)
- {
- auto it = m_mapThreads.find(item.nID);
- if(it == m_mapThreads.end())
- {
- SPDLOG_LOGGER_WARN(m_logger, "对比项线程 {} 不存在,无法更新信息", item.strName.toStdString());
- continue;
- }
- BaseCalculateThread* pThread = it.value();
- if(pThread == nullptr)
- {
- continue;
- }
- CalculateThreadInfo_t threadInfo;
- threadInfo.compareItemInfo = item;
- pThread->updateThreadInfo(threadInfo);
- }
- }
- /* 创建新的线程 */
- bool ThreadCompareItemManager::createNewCompareItemThreads(const QList<CompareItemInfo_t>& createList)
- {
- if(createList.isEmpty())
- {
- SPDLOG_LOGGER_DEBUG(m_logger, "没有新的对比项需要创建");
- return true;
- }
- for(auto& it : createList)
- {
- /* 创建新的对比项线程 */
- CalculateThreadInfo_t threadInfo;
- threadInfo.compareItemInfo = it;
- threadInfo.threadType = EThreadType::Type_CompareItem;
- threadInfo.threadState = EThreadState::State_Inited;
- CPPTP.add_task(&ThreadCompareItemManager::thread_compareItem, threadInfo);
- /* 创建线程对象 */
- // CompareItemThread* pThread = new CompareItemThread(threadInfo);
- // if(pThread == nullptr)
- // {
- // SPDLOG_LOGGER_ERROR(m_logger, "创建对比项线程 {} 失败", it.strName.toStdString());
- // return false;
- // }
-
- /* 启动线程 */
- // CPPTP.add_task(&CompareItemThread::threadTask, pThread);
-
- /* 添加到线程列表中 */
- // m_mapThreads.insert(it.nID, pThread);
- }
- return true;
- }
- /* 处理检测时段信息 */
- void ThreadCompareItemManager::processDetectPeriodInfo()
- {
- /* 获取计划信息 */
- QMap<int, DetectPeriodConfig_t> mapNewDetectConfig;
- if(!m_fromWebAPI.getDetectPeriodConfig(mapNewDetectConfig))
- {
- SPDLOG_LOGGER_ERROR(m_logger, "获取检测时段配置失败");
- return;
- }
- QMap<int, DetectPeriodConfig_t> mapUpdateDetectConfig;
- checkDetectPeriodInfo(mapNewDetectConfig, mapUpdateDetectConfig);
- }
- /* 检查获取出更新的对比项信息 */
- void ThreadCompareItemManager::checkDetectPeriodInfo(QMap<int, DetectPeriodConfig_t> newDetectInfo, QMap<int, DetectPeriodConfig_t>& updateList)
- {
- for(const auto& it : newDetectInfo)
- {
- int compareItemID = it.nID;
- for(const auto& existingItem : m_mapDetectPeriod)
- {
- if(existingItem.nID == compareItemID)
- {
- /* 已经存在的对比项,检查是否需要更新 */
- if(existingItem == it)
- {
- /* 对比项信息相同,不需要更新 */
- continue;
- } else
- {
- /* 对比项信息不同,需要更新 */
- updateList.insert(compareItemID, it);
- }
- return;
- }
- }
- }
- }
|