ThreadCompareItemManager.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. #include "ThreadCompareItemManager.h"
  2. #include "GlobalInfo.h"
  3. #include "SystemConfig.h"
  4. #include "CompareItemThread.h"
  5. #include "ThreadPool.h"
  6. ThreadCompareItemManager::ThreadCompareItemManager()
  7. {
  8. m_logger = spdlog::get("CompareItemManager");
  9. if(m_logger == nullptr)
  10. {
  11. fmt::print("ThreadCompareItemManager: CompareItemManager Logger not found.\n");
  12. return;
  13. }
  14. }
  15. ThreadCompareItemManager::~ThreadCompareItemManager()
  16. {
  17. }
  18. /* 线程函数 */
  19. void ThreadCompareItemManager::thread_CompareItemManager()
  20. {
  21. /* 初始化webapi */
  22. m_webAPIUrl = GInfo.webAPIUrl();
  23. m_webAPIID = GInfo.webAPIID();
  24. m_appType = GInfo.appType();
  25. if(!m_fromWebAPI.initWebApi(m_webAPIUrl, m_webAPIID, m_appType))
  26. {
  27. SPDLOG_LOGGER_ERROR(m_logger, "ThreadCompareItemManager: 初始化WebAPI失败");
  28. return;
  29. }
  30. /* 创建一些变量 */
  31. int threadSleepTime = 2; // 线程休眠时间,单位秒
  32. QList<CompareItemInfo_t> listCreateItems; // 新创建的对比项列表
  33. QList<CompareItemInfo_t> listUpdateItems; // 更新的对比项列表
  34. QList<int> listDeleteItems; // 删除的对比项列表
  35. /* 获取基础配置,目前只获取一次 */
  36. updateBaseSettings();
  37. SPDLOG_LOGGER_INFO(m_logger, "开启对比项管理线程");
  38. while(true)
  39. {
  40. std::this_thread::sleep_for(std::chrono::seconds(threadSleepTime));
  41. if(threadSleepTime < 10)
  42. {
  43. /* 线程睡眠时间恢复为10秒 */
  44. threadSleepTime = 10;
  45. }
  46. /* ------------------------------ 处理对比项信息 ------------------------------ */
  47. /* 获取对比项信息 */
  48. if(!m_fromWebAPI.getCompareItemInfo(m_listNewItems))
  49. {
  50. SPDLOG_LOGGER_DEBUG(m_logger, "ThreadCompareItemManager: 获取对比项失败");
  51. continue;
  52. }
  53. processCompareItemInfo(listCreateItems, listUpdateItems, listDeleteItems);
  54. SPDLOG_LOGGER_DEBUG(m_logger, "要退出的对比项个数: {}, 要更新的对比项个数: {}, 要创建的对比项个数: {}",
  55. listDeleteItems.size(), listUpdateItems.size(), listCreateItems.size());
  56. /* 先删除已消失的对比项信息 */
  57. processDeleteCompareItemThreads(listDeleteItems);
  58. /* 更新需要更新的线程 */
  59. updateRunningThreads(listUpdateItems);
  60. /* 再创建新的对比项线程 */
  61. createNewCompareItemThreads(listCreateItems);
  62. }
  63. SPDLOG_LOGGER_INFO(m_logger, "ThreadCompareItemManager: 线程结束");
  64. }
  65. /* 更新基础设置信息,如数据库设置,噪音参数等 */
  66. bool ThreadCompareItemManager::updateBaseSettings()
  67. {
  68. /* 更新基础数据 */
  69. QMap<std::string, std::string> baseSettings;
  70. if(!m_fromWebAPI.getSystemConfig(baseSettings))
  71. {
  72. SPDLOG_LOGGER_ERROR(m_logger, "获取系统配置失败");
  73. return false;
  74. }
  75. /* 将获取到的配置转换成结构体 */
  76. for(auto it = baseSettings.begin(); it != baseSettings.end(); ++it)
  77. {
  78. if(Config_Base == it.key())
  79. {
  80. if(!SysConfig.getBaseConfigFromJson(it.value()))
  81. {
  82. SPDLOG_ERROR("获取基础配置失败");
  83. }
  84. }
  85. else if(Config_CompareAI == it.key())
  86. {
  87. if(!SysConfig.getAICompareConfigFromJson(it.value()))
  88. {
  89. SPDLOG_ERROR("获取AI对比配置失败");
  90. }
  91. }
  92. else if(Config_NoiseBase == it.key())
  93. {
  94. if(!SysConfig.getNoiseDetectBaseConfigFromJson(it.value()))
  95. {
  96. SPDLOG_ERROR("获取噪音检测基础配置失败");
  97. }
  98. }
  99. else if(Config_NoiseParam == it.key())
  100. {
  101. if(!SysConfig.getNoiseDetectParamFromJson(it.value()))
  102. {
  103. SPDLOG_ERROR("获取噪音检测参数失败");
  104. }
  105. }
  106. else if(Config_Database == it.key())
  107. {
  108. if(!SysConfig.getDatabaseConfigFromJson(it.value()))
  109. {
  110. SPDLOG_ERROR("获取数据库设置失败");
  111. }
  112. }
  113. else
  114. {
  115. SPDLOG_DEBUG("未知的系统配置项: {}", it.key());
  116. }
  117. }
  118. /* 检测时段单独获取 */
  119. QMap<int, DetectPeriodConfig_t> mapDetectConfig;
  120. if(!m_fromWebAPI.getDetectPeriodConfig(mapDetectConfig))
  121. {
  122. SPDLOG_ERROR("获取对比项检测时段配置失败");
  123. return false;
  124. }
  125. SysConfig.setDetectPeriodConfig(mapDetectConfig);
  126. return true;
  127. }
  128. /**
  129. * @brief 处理对比项信息,新获取的和已有的对比
  130. *
  131. * @param createList 创建列表
  132. * @param updateList 更新列表,根据对比项ID进行更新信息
  133. * @param deleteList 删除列表
  134. */
  135. void ThreadCompareItemManager::processCompareItemInfo(QList<CompareItemInfo_t>& createList, QList<CompareItemInfo_t>& updateList, QList<int>& deleteList)
  136. {
  137. createList.clear();
  138. updateList.clear();
  139. deleteList.clear();
  140. QMap<int, CompareItemInfo_t> mapNowItems;
  141. /* 先从对比项线程中获取对比项信息 */
  142. for(auto it = m_mapThreads.begin(); it != m_mapThreads.end(); ++it)
  143. {
  144. BaseCalculateThread* pThread = it.value();
  145. if(pThread == nullptr)
  146. {
  147. continue;
  148. }
  149. /* 获取对比项信息 */
  150. CompareItemInfo_t itemInfo = pThread->getThreadInfo().compareItemInfo;
  151. mapNowItems.insert(itemInfo.nID, itemInfo);
  152. }
  153. /* 遍历新获取的对比项信息,找出需要新增的对比项和需要更新的对比项 */
  154. for(const CompareItemInfo_t& item : m_listNewItems)
  155. {
  156. if(!mapNowItems.contains(item.nID))
  157. {
  158. /* 新对比项,添加到创建列表 */
  159. createList.append(item);
  160. } else
  161. {
  162. /* 已有对比项,检查是否需要更新 */
  163. const CompareItemInfo_t& existingItem = mapNowItems.value(item.nID);
  164. /* 先对比基础信息 */
  165. if(!existingItem.isEqualBase(item))
  166. {
  167. /* 基础信息不同,需要更新 */
  168. updateList.append(item);
  169. continue;
  170. }
  171. /* 在对比对比项通道信息 */
  172. if(!existingItem.isEqualRoads(item))
  173. {
  174. /* 通道信息不同,需要更新 */
  175. updateList.append(item);
  176. continue;
  177. }
  178. }
  179. }
  180. /* 遍历当前对比项信息,找出需要删除的对比项 */
  181. for(auto it : mapNowItems)
  182. {
  183. bool isFound = false;
  184. for(const CompareItemInfo_t& newItem : m_listNewItems)
  185. {
  186. if(it.nID == newItem.nID)
  187. {
  188. isFound = true;
  189. break; // 找到对应的对比项,不需要删除
  190. }
  191. }
  192. if(!isFound)
  193. {
  194. /* 当前对比项不在新获取的对比项中,说明需要删除 */
  195. deleteList.append(it.nID);
  196. }
  197. }
  198. }
  199. /**
  200. * @brief 处理需要删除的对比项线程
  201. * 1、先处理已经停止的线程
  202. * 2、再将这次列表中的对比项ID对应的线程设置为停止状态,待到下次循环再删除已经停止完成的线程
  203. *
  204. * @param deleteList
  205. */
  206. void ThreadCompareItemManager::processDeleteCompareItemThreads(const QList<int>& deleteList)
  207. {
  208. /* 先处理已经停止运行的线程 */
  209. for(auto it = m_mapThreads.begin(); it != m_mapThreads.end();)
  210. {
  211. BaseCalculateThread* pThread = it.value();
  212. if(pThread == nullptr)
  213. {
  214. SPDLOG_LOGGER_WARN(m_logger, "对比项线程指针为空,即将删除该线程指针");
  215. it = m_mapThreads.erase(it);
  216. continue;
  217. }
  218. if(pThread->getThreadInfo().threadState == EThreadState::State_Stopped)
  219. {
  220. /* 线程已经停止,直接删除 */
  221. SPDLOG_LOGGER_INFO(m_logger, "对比项线程 {} 已经停止,准备删除", pThread->getThreadInfo().compareItemInfo.strName.toStdString());
  222. delete pThread;
  223. it = m_mapThreads.erase(it);
  224. continue;
  225. }
  226. ++it;
  227. }
  228. /* 停止本次需要停止的线程 */
  229. for(auto it : m_mapThreads)
  230. {
  231. int compareItemID = it->getThreadInfo().compareItemInfo.nID;
  232. if(deleteList.contains(compareItemID))
  233. {
  234. /* 设置线程停止标志 */
  235. it->stopThread();
  236. SPDLOG_LOGGER_INFO(m_logger, "对比项线程 {} 设置为停止状态", it->getThreadInfo().compareItemInfo.strName.toStdString());
  237. }
  238. }
  239. }
  240. /* 更新正在运行的线程信息 */
  241. void ThreadCompareItemManager::updateRunningThreads(const QList<CompareItemInfo_t>& updateList)
  242. {
  243. if(updateList.isEmpty())
  244. {
  245. return;
  246. }
  247. for(const CompareItemInfo_t& item : updateList)
  248. {
  249. auto it = m_mapThreads.find(item.nID);
  250. if(it == m_mapThreads.end())
  251. {
  252. SPDLOG_LOGGER_WARN(m_logger, "对比项线程 {} 不存在,无法更新信息", item.strName.toStdString());
  253. continue;
  254. }
  255. BaseCalculateThread* pThread = it.value();
  256. if(pThread == nullptr)
  257. {
  258. continue;
  259. }
  260. CalculateThreadInfo_t threadInfo;
  261. threadInfo.compareItemInfo = item;
  262. pThread->updateThreadInfo(threadInfo);
  263. }
  264. }
  265. /* 创建新的线程 */
  266. bool ThreadCompareItemManager::createNewCompareItemThreads(const QList<CompareItemInfo_t>& createList)
  267. {
  268. if(createList.isEmpty())
  269. {
  270. SPDLOG_LOGGER_DEBUG(m_logger, "没有新的对比项需要创建");
  271. return true;
  272. }
  273. for(auto& it : createList)
  274. {
  275. /* 创建新的对比项线程 */
  276. CalculateThreadInfo_t threadInfo;
  277. threadInfo.compareItemInfo = it;
  278. threadInfo.threadType = EThreadType::Type_CompareItem;
  279. threadInfo.threadState = EThreadState::State_Inited;
  280. /* 创建线程对象 */
  281. BaseCalculateThread* pThread = new CompareItemThread(threadInfo);
  282. if(pThread == nullptr)
  283. {
  284. SPDLOG_LOGGER_ERROR(m_logger, "创建对比项线程 {} 失败", it.strName.toStdString());
  285. return false;
  286. }
  287. /* 启动线程 */
  288. CPPTP.add_task(&CompareItemThread::threadTask, pThread);
  289. /* 添加到线程列表中 */
  290. m_mapThreads.insert(it.nID, pThread);
  291. }
  292. return true;
  293. }