在退出时一次收集用于记录到文件的调试消息的最佳方法是什么。
我正在使用c并且正在考虑使用队列系统。这是否是正确的解决方案。
我不需要复杂的解决方案。所有我需要的是调试日志字符串被存储然后释放以便在程序结束时一次性调用时写入文件,这样的例程的任何示例
答案 0 :(得分:3)
fprintf()
等已经是行缓冲的。所以它会自动为你节省一些磁盘时间。如果您坚持进一步缓冲use setvbuf()
和_IOFBF
,那么您撰写的信息流将完全缓冲。
请注意,stdout
是行缓冲的,stderr
是无缓冲的。相应地选择setvbuf
的参数!
编辑正如许多人在对该问题的评论中所指出的那样,仅当流为stdout
或stdin
时才将其置于无缓冲状态。但是当流是一个调试文件(一旦程序退出就会分析),并且你的程序有密集的日志记录并且运行很长时间,那么缓冲流是绝对有意义的。
这是一个例子,它举例说明了块写入的用法。通常,所有文件都是块缓冲的。现在,我将覆盖此行为并使用setvbuf
使其无缓冲,并让我们看看时差有多大
#include<stdio.h>
int main()
{
FILE *fp = fopen ("new.txt","w+");
int i =0;
/* Comment the below line to make fp buffered */
i=setvbuf(fp, (char*) NULL,_IONBF, 0);
if ( i )
{
printf("Error in setvbuf\n");
}
for ( long int i=1000000; i>0; i-- )
{
fprintf(fp,"Hello %ld\n",i );
}
fclose(fp);
return 0;
}
通过缓冲(即评论setvbuf
行),以下是命令的输出
time ./a.out
real 0m0.224s
user 0m0.192s
sys 0m0.020s
没有缓冲,(即启用setvbuf
)
time ./a.out
real 0m4.479s
user 0m0.752s
sys 0m3.708s
我们可以看到 4.2s !!
的巨大差异希望这可以帮助有人试图了解缓冲和记录。
答案 1 :(得分:0)
你走了:
#define SIZE_INCREMENT 10
const char **messages = NULL;
int messagesCount = 0;
int messagesSize = 0;
__attribute__((constructor))
static void initializeMessages(void)
{
messages = calloc(SIZE_INCREMENT, sizeof(const char *));
messagesSize = SIZE_INCREMENT;
}
void addMessage(const char *message)
{
if (messagesCount >= messagesSize)
{
messages = realloc(messages, messagesSize + SIZE_INCREMENT);
messagesSize += SIZE_INCREMENT;
}
messages[messagesCount] = malloc(strlen(message) + 1);
strcpy(messages[messagesCount], message);
messagesCount++;
}
__attribute__((destructor))
static void logAllMessages(void)
{
FILE *logFile = fopen("/path/to/log/file/", "w");
for (int i = 0; i < messagesCount; i++)
{
fprintf(logFile, "%s", messages[i]);
free(messages[i]);
}
free(messages);
fclose(logFile);
}