【发布时间】:2013-06-17 02:32:13
【问题描述】:
伙计们,我是线程和日志记录的初学者。 顺便说一句,我不是以英语为母语的人,如果我的英语有任何错误,请原谅我。
我创建了一个多线程软件,其中每个线程使用日志记录模块,如下所示: 每个线程使用不同的日志文件,所以我认为发生数据冲突的几率是0。
__inline void print_logW(int _level,const wchar_t *domain,const wchar_t *msg)
{
wchar_t mess[200] = _T("");
if(_level<=traceLevel)
{
__time64_t timer;
struct tm t_st;
_time64(&timer);
localtime_s(&t_st,&timer);
if (domain == NULL)
{
domain = _T("");
}
if (msg != NULL)
{
if (showTimeStampFlag == true)
{
swprintf_s(mess,200,_T("%s : %ld"),msg,GetTickCount());
}
else
{
wcscpy_s(mess,200,msg);
}
}
if(oldTime.tm_year != t_st.tm_year || oldTime.tm_mon != t_st.tm_mon || oldTime.tm_mday != t_st.tm_mday)
{
oldTime = t_st;
print_log_preparebyDateW();
}
FILE* fp;
errno_t err = _wfopen_s(&fp, this->m_pathW, _T("at+, ccs=UTF-8"));
if (err != 0)
{
// error
return;
}
fwprintf_s(fp, m_logFormatW,
_level,
1900 + t_st.tm_year, t_st.tm_mon + 1, t_st.tm_mday,
t_st.tm_hour, t_st.tm_min, t_st.tm_sec,
domain, mess
);
fflush(fp);
fclose(fp);
}
}
当我看到我制作的软件的日志时,我发现了一个问题,有时线程进程变得如此缓慢(一个进程(例如获取图像的指针)通常只需要 16 ms max,将需要 0.2 秒 或更长时间才能完成)。我还在调查这个问题的原因,但首先我想知道日志模块是否已经是线程安全的。
顺便说一下,对于参数,"_level"是打印或取消打印进程细节的日志级别
我使用"domain" 显示执行日志记录的类"msg" 是日志的内容(例如“进程 1 已启动”)
至于m_logFormatW,
m_logFormatW = _T("[%.2d][%.4d-%.2d-%.2dT%.2d:%.2d:%.2d][%s] %s\n");
如果有任何问题或不清楚的地方,请随时提出。
【问题讨论】:
-
“oldTime”从何而来?每个线程是否都有自己的包含该函数的类的实例? FWIW:当你知道一个值是无符号的时,你可能想使用“%u”。例如,您使用 32 位毫秒时间戳,每 49.7 天中的 24.85 天将变为负数,但您将它们打印为“%ld”,因此它将继续并在那里打一个减号 :)跨度>
-
不断打开和关闭
fp非常昂贵。为了加快你的日志记录:使用一个大缓冲区(32k?)并且只有在它变满时才写入;处理所有信号并确保在其处理程序中刷新并关闭日志文件。不过,您的方式要安全得多。 -
@kfsone :感谢您的建议。我会将格式从“%ld”更改为“%u”。关于“oldTime”,它实际上是记录器类的一个属性,它的数据类型为“struct tm”
-
@Dariusz :谢谢,我也想过这样做,但是由于软件有时会崩溃,所以我想知道是什么进程导致它崩溃,所以我不认为日志缓冲和刷新是个好主意。
-
@LinardiKurniawan 你抱怨日志记录很慢,所以我指出了一些原因。你用它做什么是你自己的选择:)
标签: c++ multithreading logging file-io mfc