2012-03-09 80 views
3

假设我在多线程环境中调用函数时只记录1个整数,那么实现此机制的最佳设计是什么?例如:什么是记录极少量数据的最有效方式?

void foo1() { 
    log(1); 
    ... 
} 
void foo2() { 
    log(2); 
    ... 
} 

以下是可能的方式:

  1. 只需登录到使用fprintf()文件。 问题: 为了记录1个整数而调用 函数是不是一个昂贵的操作?纠正我,如果我错了。
  2. 将记录的整数存储到数组缓冲区中;并定期刷新到文件中。 问题:如果线程崩溃,则进程将停止所有线程。所以可能,我可能会丢失很多最后的日志信息。

对高效日志记录机制有何建议?

+0

不使用开源日志框架的特殊原因? – 2012-03-09 14:06:34

+2

您应该首先担心同步访问日志文件,这可能比性能更重要。 – 2012-03-09 14:07:59

+0

回复@Als up,这里是你可以/应该使用的C++日志框架列表:http://stackoverflow.com/questions/696321/best-logging-framework-for-native-c – 2012-03-09 14:12:47

回答

0

你可以看一下日志库,比如boost日志,或者看看用互斥锁包装std :: cout,cerr,cin(或者你也记录的文件),因为有缓冲,所以它不应该'不断地写入少量的文件。

+0

是不是'fprintf()'做同样的事情? – iammilind 2012-03-09 14:13:01

+0

没有我记得* printf都是线程安全的,但是它们也是无缓冲的,因此所有打印的内容都将被写入文件(操作系统也可能会做一些缓冲),而流只在刷新时写入或者当缓冲区被填满但它们没有线程安全时 – 111111 2012-03-09 14:20:33

2

那么,“简单”的日志记录不是。 fprintf将跳转到内核(上下文切换),然后返回到程序(也是上下文切换)。速度不是很快,如果速度是你需要的。您可能还需要非常非常昂贵的sync()以确保日志数据实际上在发生电源故障时将其存入磁盘。你真的不想去那里:)

我想说,缓冲方法实际上是速度和可靠性之间最快和最合理的折衷。我要做的就是让这个缓冲区同步,以便由多个线程安全地写入。同时我会运行一个磁盘写入器线程,它会偶尔刷新数据到磁盘(取决于您拥有的数据类型)。我会使用非常基本的语言功能,进入plain C土地,只是因为某些功能(异常处理,多重继承......)在特殊情况下太容易断裂。

你可能不知道的一件事是,程序在崩溃时确实有发言权。您可以订阅程序查杀signals(某些信号可以被程序取消,但是查杀信号不是其中之一)。在进行信号处理时,您可以最后一次刷新日志缓冲区并保存更多数据。还有atexit()

+0

好的答案。所以根据你的第二种方法(在我的问题中)更好?另外,你提到的功能是平台独立的? – iammilind 2012-03-09 14:28:09

+0

是的,我认为避免连续小写入磁盘是一种更好的方法。不过,我认为你还应该添加一些标识符来记录哪些函数记录了什么(无法​​想象一个数字的用例,而没有信息来自哪里;)。是的,这些功能应该是跨平台的,至少在nix方面,很可能也是windows。 – 2012-03-09 14:59:24

+0

啊,我看,整数是标识符。在那种情况下,如果可能的话,我实际上会建议一个真正的分析器。 – 2012-03-09 15:01:10

相关问题