fix 日志并发崩溃

dev_lsy
liusiyang 1 month ago
parent 13973e9794
commit 43bd675b80

@ -14,6 +14,7 @@
#include <string.h> #include <string.h>
#include <sys/time.h> #include <sys/time.h>
#include <vector> #include <vector>
#include <mutex>
#include "ImgCheckConfig.h" #include "ImgCheckConfig.h"
#include "CheckErrorCodeDefine.hpp" #include "CheckErrorCodeDefine.hpp"
using namespace std; using namespace std;
@ -62,17 +63,29 @@ struct DetLog
bool bPrintStr; // 是否打印日志 bool bPrintStr; // 是否打印日志
int addLogLevel; int addLogLevel;
// 保护 logList:同一个 DetLog(如图片结果的日志)会被实例主线程(Run/CheckRun)
// 与任务线程(AI 推理/分类) 并发写入,无锁 push_back 会造成 vector 堆破坏。
std::mutex mtx_log;
DetLog() DetLog()
{ {
Init(); Init();
} }
void Init() void Init()
{ {
std::lock_guard<std::mutex> lock(mtx_log);
logList.clear(); logList.clear();
bPrintStr = false; bPrintStr = false;
addLogLevel = DET_LOG_LEVEL_3; addLogLevel = DET_LOG_LEVEL_3;
} }
// 线程安全地获取日志快照
std::vector<std::string> GetLogs()
{
std::lock_guard<std::mutex> lock(mtx_log);
return logList;
}
template <typename... Args> template <typename... Args>
void AddCheckstr(PrintLevel_ step, std::string stepStr, const std::string &format, Args... args) void AddCheckstr(PrintLevel_ step, std::string stepStr, const std::string &format, Args... args)
{ {
@ -105,6 +118,7 @@ struct DetLog
printf("%s\n", str.c_str()); printf("%s\n", str.c_str());
} }
std::lock_guard<std::mutex> lock(mtx_log);
logList.push_back(str); logList.push_back(str);
} }
template <typename... Args> template <typename... Args>
@ -141,16 +155,20 @@ struct DetLog
if (LogLevel <= addLogLevel) if (LogLevel <= addLogLevel)
{ {
std::lock_guard<std::mutex> lock(mtx_log);
logList.push_back(str); logList.push_back(str);
} }
} }
void printLog(std::string str) void printLog(std::string str)
{ {
printf("===========================%s==============================\n", str.c_str()); printf("===========================%s==============================\n", str.c_str());
{
std::lock_guard<std::mutex> lock(mtx_log);
for (auto strl : logList) for (auto strl : logList)
{ {
printf("%s\n", strl.c_str()); printf("%s\n", strl.c_str());
} }
}
printf("==========================================================\n"); printf("==========================================================\n");
} }
}; };

@ -789,7 +789,10 @@ int CameraCheckAnalysisy::CheckImgRun()
if (m_pCheck_Result->getImgPushComplate()) if (m_pCheck_Result->getImgPushComplate())
{ {
curcheckStep = Check_Step_Complete; // 进入到预图片检测阶段 curcheckStep = Check_Step_Complete; // 进入到预图片检测阶段
m_pCheck_Result->SetCheckStep(curcheckStep); // 注意:这里先不发布 Check_Step_Complete。
// 若提前发布,ALLImgCheckAnalysisy 线程会立刻把结果塞给 deal,
// 而本线程还在 InsertCameraLog() 里写 result->det_LogList,两边并发(读/写)竞争。
// 因此把 SetCheckStep(Check_Step_Complete) 挪到 InsertCameraLog() 之后。
} }
else else
{ {
@ -806,6 +809,8 @@ int CameraCheckAnalysisy::CheckImgRun()
m_pdetlog->AddCheckstr(PrintLevel_0, "CheckImgRun", "========came %s Check ALL end time %ld ms %s", m_pdetlog->AddCheckstr(PrintLevel_0, "CheckImgRun", "========came %s Check ALL end time %ld ms %s",
m_pCheck_Result->cameraBaseResult->strCameraName.c_str(), tend - m_pCheck_Result->time_start, strTimg.c_str()); m_pCheck_Result->cameraBaseResult->strCameraName.c_str(), tend - m_pCheck_Result->time_start, strTimg.c_str());
InsertCameraLog(); InsertCameraLog();
// 日志拼接完成后再发布“检测完成”,避免 deal 提前读到正在写入的 det_LogList
m_pCheck_Result->SetCheckStep(Check_Step_Complete);
std::lock_guard<std::mutex> lock(mtx_WaiteImg); std::lock_guard<std::mutex> lock(mtx_WaiteImg);
m_bHaveImgeDet = false; m_bHaveImgeDet = false;
@ -850,8 +855,12 @@ int CameraCheckAnalysisy::InsertCameraLog()
} }
// 1、把图片的相关日志 写到 返回 日志中。 // 1、把图片的相关日志 写到 返回 日志中。
// 注意:DetLog 可能仍被实例线程写入,使用 GetLogs() 做加锁快照,避免并发遍历。
{
std::vector<std::string> imgLogs = pImageResult->detlog->GetLogs();
m_CheckResult_shareP->det_LogList.insert(m_CheckResult_shareP->det_LogList.end(), m_CheckResult_shareP->det_LogList.insert(m_CheckResult_shareP->det_LogList.end(),
pImageResult->detlog->logList.begin(), pImageResult->detlog->logList.end()); imgLogs.begin(), imgLogs.end());
}
std::string str = ""; std::string str = "";
char buffer[256]; char buffer[256];
// 2、把缺陷信息 写的 返回日志中。 // 2、把缺陷信息 写的 返回日志中。
@ -882,8 +891,9 @@ int CameraCheckAnalysisy::InsertCameraLog()
if (QX_info->result == QX_RESULT_TYPE_NG) if (QX_info->result == QX_RESULT_TYPE_NG)
{ {
std::shared_ptr<DetLog> pQxLog = pDetResult->pQx_ErrorList->at(qxidx).detlog; std::shared_ptr<DetLog> pQxLog = pDetResult->pQx_ErrorList->at(qxidx).detlog;
std::vector<std::string> qxLogs = pQxLog->GetLogs();
m_CheckResult_shareP->det_LogList.insert(m_CheckResult_shareP->det_LogList.end(), m_CheckResult_shareP->det_LogList.insert(m_CheckResult_shareP->det_LogList.end(),
pQxLog->logList.begin(), pQxLog->logList.end()); qxLogs.begin(), qxLogs.end());
} }
} }
@ -899,8 +909,9 @@ int CameraCheckAnalysisy::InsertCameraLog()
if (QX_info->result == QX_RESULT_TYPE_YS) if (QX_info->result == QX_RESULT_TYPE_YS)
{ {
std::shared_ptr<DetLog> pQxLog = pDetResult->pQx_ErrorList->at(qxidx).detlog; std::shared_ptr<DetLog> pQxLog = pDetResult->pQx_ErrorList->at(qxidx).detlog;
std::vector<std::string> qxLogs = pQxLog->GetLogs();
m_CheckResult_shareP->det_LogList.insert(m_CheckResult_shareP->det_LogList.end(), m_CheckResult_shareP->det_LogList.insert(m_CheckResult_shareP->det_LogList.end(),
pQxLog->logList.begin(), pQxLog->logList.end()); qxLogs.begin(), qxLogs.end());
} }
} }
@ -916,8 +927,9 @@ int CameraCheckAnalysisy::InsertCameraLog()
if (QX_info->result == QX_RESULT_TYPE_OK) if (QX_info->result == QX_RESULT_TYPE_OK)
{ {
std::shared_ptr<DetLog> pQxLog = pDetResult->pQx_ErrorList->at(qxidx).detlog; std::shared_ptr<DetLog> pQxLog = pDetResult->pQx_ErrorList->at(qxidx).detlog;
std::vector<std::string> qxLogs = pQxLog->GetLogs();
m_CheckResult_shareP->det_LogList.insert(m_CheckResult_shareP->det_LogList.end(), m_CheckResult_shareP->det_LogList.insert(m_CheckResult_shareP->det_LogList.end(),
pQxLog->logList.begin(), pQxLog->logList.end()); qxLogs.begin(), qxLogs.end());
} }
} }
@ -933,8 +945,9 @@ int CameraCheckAnalysisy::InsertCameraLog()
if (QX_info->result == QX_RESULT_TYPE_NoJduge) if (QX_info->result == QX_RESULT_TYPE_NoJduge)
{ {
std::shared_ptr<DetLog> pQxLog = pDetResult->pQx_ErrorList->at(qxidx).detlog; std::shared_ptr<DetLog> pQxLog = pDetResult->pQx_ErrorList->at(qxidx).detlog;
std::vector<std::string> qxLogs = pQxLog->GetLogs();
m_CheckResult_shareP->det_LogList.insert(m_CheckResult_shareP->det_LogList.end(), m_CheckResult_shareP->det_LogList.insert(m_CheckResult_shareP->det_LogList.end(),
pQxLog->logList.begin(), pQxLog->logList.end()); qxLogs.begin(), qxLogs.end());
} }
} }
} }
@ -946,8 +959,11 @@ int CameraCheckAnalysisy::InsertCameraLog()
} }
// 3、把相机的日志 写到 返回日志中。 // 3、把相机的日志 写到 返回日志中。
{
std::vector<std::string> camLogs = m_pCheck_Result->detlog->GetLogs();
m_CheckResult_shareP->det_LogList.insert(m_CheckResult_shareP->det_LogList.end(), m_CheckResult_shareP->det_LogList.insert(m_CheckResult_shareP->det_LogList.end(),
m_pCheck_Result->detlog->logList.begin(), m_pCheck_Result->detlog->logList.end()); camLogs.begin(), camLogs.end());
}
{ {
sprintf(buffer, " =====================Product Log ============================="); sprintf(buffer, " =====================Product Log =============================");
@ -955,8 +971,11 @@ int CameraCheckAnalysisy::InsertCameraLog()
m_CheckResult_shareP->det_LogList.push_back(str); m_CheckResult_shareP->det_LogList.push_back(str);
} }
// 4、把产品相关日志 写到 返回日志中。 // 4、把产品相关日志 写到 返回日志中。
{
std::vector<std::string> productLogs = m_pCheck_Result->productBaseResult->detlog->GetLogs();
m_CheckResult_shareP->det_LogList.insert(m_CheckResult_shareP->det_LogList.end(), m_CheckResult_shareP->det_LogList.insert(m_CheckResult_shareP->det_LogList.end(),
m_pCheck_Result->productBaseResult->detlog->logList.begin(), m_pCheck_Result->productBaseResult->detlog->logList.end()); productLogs.begin(), productLogs.end());
}
} }
return 0; return 0;
} }

@ -18,7 +18,7 @@
#define HANDLE_SIZE_MIN_RATIO 0.8f #define HANDLE_SIZE_MIN_RATIO 0.8f
#define HANDLE_SIZE_MAX_RATIO 1.2f #define HANDLE_SIZE_MAX_RATIO 1.2f
// "附近"的搜索范围:把手区域外接矩形在宽/高方向各外扩该比例 // "附近"的搜索范围:把手区域外接矩形在宽/高方向各外扩该比例
#define HANDLE_NEAR_EXPAND_RATIO 0.5f #define HANDLE_NEAR_EXPAND_RATIO 5
// 凸起填充率下限等参数的默认值在 Handle_Check_Param(CheckConfigDefine.h)里 // 凸起填充率下限等参数的默认值在 Handle_Check_Param(CheckConfigDefine.h)里
// 用于排序轮廓的比较函数 // 用于排序轮廓的比较函数

Loading…
Cancel
Save