¿Cuál es la forma más eficaz de registrar una cantidad muy pequeña de datos?

Suppose I am logging only 1 integer when a function is called in multi-threaded environment, then what is the best design to implement this mechanism ? Example:

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

Following are the possible ways:

  1. Simply log into the file using fprintf(). Problema: Isn't it an expensive operation to call a function just to log 1 integer ? Correct me if I am wrong.
  2. Store logged integers into an array buffer; and flush periodically into a file. Problema: If a thread crashes, then process would stop all the threads. So possibly, I may loose lot of last log info.

Any more suggestion for efficient logging mechanism ?

preguntado el 09 de marzo de 12 a las 13:03

Any particular reason for not using open source logging frameworks? -

You should first worry about synchronizing the accesses to the log file, this is probably a bigger issue than performance. -

To back @Als up, here is a list of C++ logging frameworks that you could/should use: stackoverflow.com/questions/696321/… -

@LucTouraille: I cannot agree more, standard library functions are No seguro para subprocesos, So eventually there has to be some synchronization or perhaps a Queuing mechanism in place for using those library functions, and this should be more of a concern than which api to use for logging. -

@Als, it's a small time logging mechanism; for that adding an open source framework may not be accepted by others. I need to use only the standard library mechanism like, fprintf, fstream ....

2 Respuestas

Well, "simple" logging isn't. fprintf will make a jump to kernel (context switch), then back to program (also context switch). Ain't fast, if speed is what you need. You'd probably also need a very, very expensive sync() to make sure the logging data actually makes it to the disk in case of power failure. You really don't want to go there :)

I'd say that the buffered method is actually the fastest and most reasonable tradeoff between speed and reliability. What I'd do is have that buffer, synchronized to be safely written by multiple threads. Concurrently I'd run a disk-writer thread that would flush data to disk once in a while (depends a lot on kind of data you have). I'd use very basic language feature, going more into the plain C land, just because some features (exception handling, multiple inheritance..) are just too prone to break in special circumstances.

One thing you maybe don't know, is that programs do have a say when they crash. You can subscribe to program killing señales (some signals can be cancelled by program, but killing signal isn't one of them). While you're in signal handling, you can flush the log buffer one last time and save more data. And there is also atexit().

respondido 09 mar '12, 14:03

Good answer. So according to you 2nd approach (in my question) is better ? Also, the the functions you mentioned are platform independent ? - iammilind

Yes, I think avoiding continuous small writes to disk is a better approach. However I think you should also add some identifier of which function logged what (can't imagine a use case for a number without info where it came from ;). And yes, these functions should be cross platform, at least on *nix side, most likely windows too. - Pasi Savolainen

Ah, I see, the integer is the identifier. In that case I'd actually suggest a real profiler, if at all possible. - Pasi Savolainen

You could either take a look at a logging library like boost log or alternatively look at wrapping up std::cout, cerr, cin (or the file you log too) with mutexes, because there are buffered then it shouldn't continuously be writing small amounts to the file.

respondido 09 mar '12, 14:03

No es fprintf() do the same thing ? - iammilind

no as far as I can remember the *printf are all thread safe, however they are also unbuffered so everything printed will be written to the file (well the OS will probably do some buffering too) where as stream only write when they are flushed or when the buffer is filled but they are no thread safe - 111111

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.