修复VrUtils单一初始化
This commit is contained in:
parent
4d9f7170ee
commit
3756a63a32
@ -148,7 +148,7 @@ win32:CONFIG(release, debug|release): {
|
||||
}
|
||||
else:win32:CONFIG(debug, debug|release): {
|
||||
LIBS += -L$$PWD/../../../AppAlgo/particleSizeMeasure/Windows/x64/Debug -lparticleSizeMeasurement -lbaseAlgorithm
|
||||
LIBS += -L$$PWD/../../../SDK/OpenCV320/Windows/vc14/Debug -lopencv_world320d
|
||||
LIBS += -L$$PWD/../../../SDK/OpenCV320/Windows/vc14/Release -lopencv_world320
|
||||
}
|
||||
else:unix:!macx: {
|
||||
LIBS += -L$$PWD/../../../AppAlgo/particleSizeMeasure/Arm/aarch64 -lparticleSizeMeasurement -lbaseAlgorithm
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
|
||||
#include <QThread>
|
||||
#include <QApplication>
|
||||
#include <QCoreApplication>
|
||||
#include <QDateTime>
|
||||
#include <cmath>
|
||||
|
||||
@ -24,6 +25,16 @@ WheelMeasurePresenter::WheelMeasurePresenter(QObject* parent)
|
||||
|
||||
WheelMeasurePresenter::~WheelMeasurePresenter()
|
||||
{
|
||||
// 清除状态回调,防止后续回调访问已销毁对象
|
||||
m_statusUpdate = nullptr;
|
||||
|
||||
// 停止顺序检测
|
||||
m_stopSequentialRequested = true;
|
||||
m_sequentialDetecting = false;
|
||||
|
||||
// 处理待处理的 Qt 事件,确保 QueuedConnection 的回调不会访问已销毁对象
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
if (m_config) {
|
||||
delete m_config;
|
||||
m_config = nullptr;
|
||||
|
||||
@ -41,9 +41,6 @@ win32:CONFIG(debug, debug|release) {
|
||||
LIBS += -L../../../AppUtils/AppCommon/debug -lAppCommon
|
||||
LIBS += -L../../../Module/ModbusTCPServer/debug -lModbusTCPServer
|
||||
LIBS += -L../../../VrNets/debug -lVrModbus
|
||||
|
||||
# VzNLSDK
|
||||
LIBS += -L../../../SDK/Device/VzNLSDK/Windows/x64/Debug -lVzKerneld
|
||||
} else:win32:CONFIG(release, debug|release) {
|
||||
LIBS += -L../WheelMeasureConfig/release -lWheelMeasureConfig
|
||||
LIBS += -L../../../VrNets/release -lVrTcpClient
|
||||
@ -54,9 +51,6 @@ win32:CONFIG(debug, debug|release) {
|
||||
LIBS += -L../../../AppUtils/AppCommon/release -lAppCommon
|
||||
LIBS += -L../../../Module/ModbusTCPServer/release -lModbusTCPServer
|
||||
LIBS += -L../../../VrNets/release -lVrModbus
|
||||
|
||||
# VzNLSDK
|
||||
LIBS += -L../../../Device/VrEyeDevice/release -lVrEyeDevice
|
||||
}else:unix:!macx {
|
||||
# 注意:静态库链接顺序很重要,被依赖的库必须放在后面
|
||||
LIBS += -L../WheelMeasureConfig -lWheelMeasureConfig
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include <fstream>
|
||||
#include <QFileInfo>
|
||||
#include <QString>
|
||||
#include <QCoreApplication>
|
||||
#include "PathManager.h"
|
||||
#include "IYModbusTCPServer.h"
|
||||
|
||||
@ -22,11 +23,17 @@ BasePresenter::BasePresenter(QObject *parent)
|
||||
|
||||
BasePresenter::~BasePresenter()
|
||||
{
|
||||
// 清除状态回调指针,防止后续回调访问
|
||||
m_pStatusCallback = nullptr;
|
||||
|
||||
// 等待初始化线程完成
|
||||
if (m_initThread.joinable()) {
|
||||
m_initThread.join();
|
||||
}
|
||||
|
||||
// 处理待处理的 Qt 事件,确保 QueuedConnection 的回调执行时检查到 m_pStatusCallback 为空
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
// 停止检测线程
|
||||
StopAlgoDetectThread();
|
||||
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
#include <cstring>
|
||||
#include <stdarg.h>
|
||||
#include <clocale>
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
|
||||
#include <log4cpp/Category.hh>
|
||||
#include <log4cpp/Appender.hh>
|
||||
@ -41,10 +43,29 @@
|
||||
#define LOG_CONFIG_FILE "config.ini"
|
||||
#define LOG_PRINT_FILE "AppLog.log"
|
||||
|
||||
static log4cpp::PatternLayout* m_pLayout = nullptr;
|
||||
static log4cpp::RollingFileAppender* m_prollfileAppender = nullptr;
|
||||
static bool g_isLogInitialized = false;
|
||||
static bool g_isTimeEnabled = true;
|
||||
// 使用函数内静态变量实现真正的全局单例(跨静态库安全)
|
||||
struct VrLogState {
|
||||
log4cpp::PatternLayout* pLayout = nullptr;
|
||||
log4cpp::RollingFileAppender* pRollFileAppender = nullptr;
|
||||
std::atomic<bool> isInitialized{false};
|
||||
std::atomic<bool> isShutdown{false}; // 标记日志系统是否已关闭(程序退出时)
|
||||
std::atomic<bool> isTimeEnabled{true};
|
||||
std::once_flag initFlag;
|
||||
std::once_flag uninitFlag;
|
||||
};
|
||||
|
||||
// 函数内静态变量,确保跨编译单元的唯一性
|
||||
static VrLogState& GetLogState() {
|
||||
static VrLogState state;
|
||||
return state;
|
||||
}
|
||||
|
||||
// 兼容旧代码的访问方式
|
||||
#define m_pLayout (GetLogState().pLayout)
|
||||
#define m_prollfileAppender (GetLogState().pRollFileAppender)
|
||||
#define g_isLogInitialized (GetLogState().isInitialized)
|
||||
#define g_isLogShutdown (GetLogState().isShutdown)
|
||||
#define g_isTimeEnabled (GetLogState().isTimeEnabled)
|
||||
|
||||
|
||||
#ifdef STM32_UCOSIII
|
||||
@ -165,14 +186,9 @@ public:
|
||||
// 静态实例,程序启动时自动初始化日志,程序退出时自动清理日志
|
||||
static VrLogAutoCleaner g_logAutoCleaner;
|
||||
|
||||
/// 初始化log
|
||||
void VrLogUtils::InitLog()
|
||||
// 实际执行初始化的内部函数
|
||||
static void DoInitLog()
|
||||
{
|
||||
// 防止重复初始化
|
||||
if (g_isLogInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
// 设置控制台代码页为 UTF-8,解决中文乱码
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
@ -204,25 +220,26 @@ void VrLogUtils::InitLog()
|
||||
}
|
||||
|
||||
// create file appender
|
||||
if (nullptr == m_pLayout)
|
||||
VrLogState& state = GetLogState();
|
||||
if (nullptr == state.pLayout)
|
||||
{
|
||||
m_pLayout = new log4cpp::PatternLayout;
|
||||
state.pLayout = new log4cpp::PatternLayout;
|
||||
// 设置布局格式,可以控制是否自动换行
|
||||
// %d{%Y-%m-%d %H:%M:%S.%l} [%p] %c - %m%n
|
||||
// 其中 %n 表示换行符,如果想要控制换行可以去掉或修改这个
|
||||
m_pLayout->setConversionPattern("%d{%Y-%m-%d %H:%M:%S.%l} [%p] %m");
|
||||
state.pLayout->setConversionPattern("%d{%Y-%m-%d %H:%M:%S.%l} [%p] %m");
|
||||
}
|
||||
if (nullptr == m_prollfileAppender)
|
||||
if (nullptr == state.pRollFileAppender)
|
||||
{
|
||||
m_prollfileAppender = new log4cpp::RollingFileAppender("AppLogAppender", logPath + PATH_SEP + LOG_PRINT_FILE,
|
||||
state.pRollFileAppender = new log4cpp::RollingFileAppender("AppLogAppender", logPath + PATH_SEP + LOG_PRINT_FILE,
|
||||
1024 * 1024, // 单个文件大小1M
|
||||
10); // 10个文件
|
||||
|
||||
m_prollfileAppender->setLayout(m_pLayout);
|
||||
state.pRollFileAppender->setLayout(state.pLayout);
|
||||
|
||||
// add appender to category
|
||||
log4cpp::Category& root = log4cpp::Category::getRoot();
|
||||
root.addAppender(m_prollfileAppender);
|
||||
root.addAppender(state.pRollFileAppender);
|
||||
|
||||
// set priority
|
||||
root.setPriority(log4cpp::Priority::DEBUG);
|
||||
@ -232,27 +249,41 @@ void VrLogUtils::InitLog()
|
||||
g_isLogInitialized = true;
|
||||
}
|
||||
|
||||
/// 关闭log
|
||||
void VrLogUtils::UninitLog()
|
||||
/// 初始化log
|
||||
void VrLogUtils::InitLog()
|
||||
{
|
||||
if (!g_isLogInitialized) {
|
||||
// 如果已经关闭,不再初始化
|
||||
if (g_isLogShutdown) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pLayout)
|
||||
{
|
||||
delete m_pLayout;
|
||||
m_pLayout = nullptr;
|
||||
}
|
||||
|
||||
if (m_prollfileAppender)
|
||||
{
|
||||
delete m_prollfileAppender;
|
||||
m_prollfileAppender = nullptr;
|
||||
}
|
||||
log4cpp::Category::shutdown();//关闭Category;
|
||||
// 使用 call_once 确保只执行一次初始化(跨静态库安全)
|
||||
std::call_once(GetLogState().initFlag, DoInitLog);
|
||||
}
|
||||
|
||||
// 实际执行清理的内部函数
|
||||
static void DoUninitLog()
|
||||
{
|
||||
// 先设置标志,防止其他线程继续调用日志
|
||||
g_isLogInitialized = false;
|
||||
g_isLogShutdown = true; // 标记已关闭,防止 EchoLog 重新初始化
|
||||
|
||||
// 注意:不调用 log4cpp::Category::shutdown()
|
||||
// 原因:静态对象析构顺序不确定,log4cpp 内部的静态对象可能在
|
||||
// VrLogAutoCleaner 之前就已经被析构,此时调用 shutdown() 会崩溃。
|
||||
// 程序退出时,操作系统会自动回收所有内存,不需要手动清理。
|
||||
|
||||
// 只置空指针,不删除对象(对象由 log4cpp 内部管理)
|
||||
VrLogState& state = GetLogState();
|
||||
state.pLayout = nullptr;
|
||||
state.pRollFileAppender = nullptr;
|
||||
}
|
||||
|
||||
/// 关闭log
|
||||
void VrLogUtils::UninitLog()
|
||||
{
|
||||
// 使用 call_once 确保只执行一次清理(跨静态库安全)
|
||||
std::call_once(GetLogState().uninitFlag, DoUninitLog);
|
||||
}
|
||||
|
||||
|
||||
@ -269,6 +300,11 @@ void VrLogUtils::EnableTime(bool bEnable)
|
||||
/// 输出log
|
||||
void VrLogUtils::EchoLog(VrLogLevel eLogLevel, const char* sFilePath, const int nLine, const char* sLogGroup, const char* sFormat, ...)
|
||||
{
|
||||
// 如果日志系统已关闭(程序退出),直接返回,不要重新初始化
|
||||
if (g_isLogShutdown) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 由于VrLogAutoCleaner会在程序启动时自动初始化,这里只做保险检查
|
||||
if (!g_isLogInitialized) {
|
||||
InitLog();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user