C++ 自定义的线程安全的LOG_PRINTF
1、log.h中宏定义
#ifndef LOG_H
#define LOG_H
#include <stdio.h>
#include <iostream>
#include <chrono>
#include <ctime>
#include <mutex>
// 获取现在时间->
#define LOG_PRINTF(format, ...) do{ \
static std::mutex log_mutex;\
auto now = std::chrono::system_clock::now();\
std::time_t now_time_t = std::chrono::system_clock::to_time_t(now);\
auto duration = now.time_since_epoch();\
auto milliseconds = static_cast<int>(std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() % 1000);\
std::lock_guard<std::mutex> guard(log_mutex);\
std::tm now_tm; \
localtime_s(&now_tm, &now_time_t);\
printf("[%04d-%02d-%02d %02d:%02d:%02d.%03d]" format, \
now_tm.tm_year + 1900 , now_tm.tm_mon + 1, now_tm.tm_mday, \
now_tm.tm_hour, now_tm.tm_min , now_tm.tm_sec, milliseconds, ##__VA_ARGS__);\
}while(0)
#endif // LOG_H
2、main.cpp 使用
FILE *logFile = freopen("log.txt","a",stdout);
if(logFile == NULL) {
perror("Failed to open or creat log file");
}
fclose(logFile); // 关闭文件,退出程序使用
3、Qt 中使用示例
3.1 修改前
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec(); // 运行 Qt 事件循环
}
3.2 修改后
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
FILE *logFile = freopen("log.txt","a",stdout);
if(logFile == NULL) {
perror("Failed to open or creat log file");
}
MainWindow w;
w.show();
int result = a.exec(); // 运行 Qt 事件循环
fclose(logFile); // 退出 Qt 事件循环后关闭日志文件
return result;
}
3.3 遗留问题(宏中条件编译的问题)
- Windows线程安全(C++ MSVC):
#include <ctime> //注: 无.h后缀(继承并包含了time.h) localtime_s(&now_tm, &now_time_t); - Linux(POSIX)线程安全(C++ MinGW):
#include <ctime> localtime_r(&now_time_t, &now_tm); - Std::localtime 函数延伸
- localtime() -> Std::localtime() -> localtime_s() 或 localtime_r()
- C语言:#include <time.h> 调用的localtime是非线程安全的
- C++的std中并未提供 localtime_s和 localtime_r 两个函数,对C++的支持是由编译器决定的,因为编译时都是在编译器的include目录中找的
本文来自博客园,作者:变秃了也就变强了,转载请注明原文链接:https://www.cnblogs.com/lichangyi/p/18712168

浙公网安备 33010602011771号