当前位置: 首页 > news >正文

C++ 自定义简单的异步日志类

C++ 自定义简单的异步日志类

背景:在项目中由于将写日志功能放到了主线程中,导致主线程执行某个功能时会造成界面的卡顿。在调试程序过程中,发现是频繁的同步写日志操作导致界面卡顿。在把同步写日志函数注释后,函数执行不再卡顿,功能也正常。但是该功能没有写入日志信息了。这样操作就不能更好的排查问题了。所以就采用异步写日志的方法。

自定义异步日志类:

.h文件

#pragma once
#include<afx.h>
#include<afxmt.h>
#include<afxwin.h>
#include<windows.h>
#include<deque>
#include<string>
#include<fstream>
using namespace std;
class CAsyncLog
{
public:static CAsyncLog& Instance();void Log(const CString& strLog);void Stop();private:CAsyncLog();~CAsyncLog();static UINT WriteLogThread(LPVOID lpvoid);void SwapBuffers();void WriteToFile(deque<string>& buffer);bool m_bRuning;CWinThread* m_pThread;// 前端缓冲区deque<string> m_frontBuffer;// 后端缓冲区deque<string> m_backBuffer;// 临界区,实现线程同步CCriticalSection m_cs;// 输出文件ofstream m_file;
};

.cpp文件

#include <time.h>
CAsyncLog& CAsyncLog::Instance()
{static CAsyncLog m_asyncLog;return m_asyncLog;
}CAsyncLog::CAsyncLog()
{TCHAR szPath[MAX_PATH];::GetModuleFileName(NULL,szPath,MAX_PATH);CString strFile(szPath);strFile = strFile.Left(strFile.ReverseFind('\\')+ 1);strFile += _T("app.log");m_bRuning = true;m_file.open(strFile.GetBuffer(),ios::app);strFile.ReleaseBuffer();m_pThread = AfxBeginThread(WriteLogThread,this);
}CAsyncLog::~CAsyncLog()
{Stop();
}UINT CAsyncLog::WriteLogThread(LPVOID lpvoid)
{CAsyncLog* pAsyncLog = (CAsyncLog*)lpvoid;while (pAsyncLog->m_bRuning){// 每100ms查询一次::Sleep(100);pAsyncLog->SwapBuffers();}// 线程退出前写入剩余的日志信息pAsyncLog->SwapBuffers();return 0;
}void CAsyncLog::Log(const CString& strText)
{CSingleLock lock(&m_cs,TRUE);CTime tm = CTime::GetCurrentTime();CString strTime = tm.Format(_T("[%Y-%m-%d %H:%M:%S] "));// 转换为streamCStringA strBuffer(strTime + strText);string strLog = static_cast<const char*>(strBuffer);m_frontBuffer.push_back(strLog);
}void CAsyncLog::Stop()
{m_bRuning = false;if (m_pThread){::WaitForSingleObject(m_pThread->m_hThread,5000);m_pThread = nullptr;}if (m_file.is_open()){m_file.close();}
}void CAsyncLog::WriteToFile(deque<string>& buffer)
{deque<string>::const_iterator it = buffer.begin();for (;it != buffer.end();it++){m_file << *it << "\r\n";}m_file.flush();
}void CAsyncLog::SwapBuffers()
{CSingleLock lock(&m_cs,TRUE);if (m_frontBuffer.empty())return;m_frontBuffer.swap(m_backBuffer);WriteToFile(m_backBuffer);m_backBuffer.clear();
}

该类的使用方式是:

#include <iostream>
#include"AsyncLog.h"int main()
{for (int i=0;i<10;i++){CString str;str.Format(_T("AsyncLog Test,%d"),i);CAsyncLog::Instance().Log(str);}std::cout << "Hello World!\n";
}

说明:日志生成再当前软件的运行目录下。

http://www.dtcms.com/a/311794.html

相关文章:

  • oect刷入arm系统安装docker
  • Python深度学习:从入门到精通
  • retro-go 1.45 编译及显示中文
  • 联合索引全解析:一棵树,撑起查询的半边天
  • 【01】OpenCV C#——C#开发环境OpenCvSharp 环境配置 工程搭建 及代码测试
  • 【QT】Qt信号与槽机制详解信号和槽的本质自定义信号和槽带参数的信号和槽
  • 计算机网络:为什么IPv6没有选择使用点分十进制
  • 数据结构初学习、单向链表
  • Python 字典为什么查询高效
  • 数据结构---概念、数据与数据之间的关系(逻辑结构、物理结构)、基本功能、数据结构内容、单向链表(该奶奶、对象、应用)
  • SpringBoot3.x入门到精通系列:2.2 依赖注入与IoC容器
  • Spring AI MCP 服务端
  • 边缘智能网关在水务行业中的应用—龙兴物联
  • 沿街晾晒识别准确率↑32%:陌讯多模态融合算法实战解析
  • P2415 集合求和
  • Docker 镜像打包为 ZIP 文件便于分享和转发
  • linux ext4缩容home,扩容根目录
  • 【Kubernetes】Secret配置管理,安全管理敏感配置
  • Effective C++ 条款17:以独立语句将newed对象置入智能指针
  • Python 程序设计讲义(50):Python 的可迭代对象与迭代器
  • Flutter基础知识
  • SpringBoot与TurboGears2跨栈、整合AI服务、智能客服路由系统整合实战
  • SpringCloud学习第一季-4
  • 第15届蓝桥杯Python青少组中/高级组选拔赛(STEMA)2024年3月10日真题
  • 17、原坐标变换和逆变换在实战中用法
  • 无人机数字图传技术的前沿探索与应用
  • 【昇腾推理PaddleOCR】生产级部署方式
  • 机器学习实战:KNN算法全解析 - 从原理到创新应用
  • LangChain框架入门05:输出解析器使用技巧
  • SpringBoot 服务器配置