ab1127
ab1127

Reputation: 95

Mutiple loggers writing to one file C++

I am trying to implement a logging scenario where there are multiple loggers for different components within a project. All these loggers try to write to a file. Is there any library to this or some way to synchronize the activity in C++(as in Java).

Also a single handle is shared.

Upvotes: 1

Views: 278

Answers (4)

Tony Delroy
Tony Delroy

Reputation: 106216

A mutex is a portable and guaranteed approach.

While not guaranteed to work, in common implementations the output from any single ofstream << x operation is never intermingled with other threads' operations on the same stream (i.e. the fstream presumably uses a mutex or carefully constructed lock-free en-queuing internally), so if you avoid doing this...

my_ofstream << x << y << '\n';  // troublesome: 3 fstream operations

...in favour of this...

std::ostringstream oss;
oss << x << y << '\n';
my_ofstream << oss.rdbuf();   // usually ok: 1 fstream operation

...you can keep your output lines together. For logging this is often easy to orchestrate centrally inside logging macros. For distributed file I/O it's a nuisance. Preparing data in a local ostringstream then copying it is clearly more work overall, but at least such work can be carried out by many threads concurrently, with the copy to the single ofstream object then very fast. For implementations that do use some internal synchronisation, wrapping your own external synchronisation around your en-queuing would slow things down unnecessarily.

Upvotes: 0

Anil8753
Anil8753

Reputation: 2735

Implement a thread safe Queue, all components of your application will push log message to your Queue. From this Queue pop Messages and write to your log file.

Upvotes: 0

Kingsley
Kingsley

Reputation: 14916

You could add a mutex to your logging code. This will protect it from concurrency because only one thread can lock the mutex at once, the others wait on the lock call.

Under UNIX you can use p_threads mutex, and critical sections under Win32.

CRITICAL_SECTION my_mutex;

void initialise()
{
    InitializeCriticalSection(&my_mutex);
}

void log(const char *some text)
{
    EnterCriticalSection(&my_mutex);

    // do some logging

    LeaveCriticalSection(&my_mutex);
}

Under UNIX is much the same, except use:

pthread_mutex_t my_mutex;
pthread_mutex_init(&my_mutex, NULL);   /// instead of InitializeCriticalSection()
pthread_mutex_lock(&my_mutex);         /// instead of EnterCriticalSection()
pthread_mutex_unlock(&my_mutex);       /// instead of LeaveCriticalSection()

Upvotes: 0

SailorCire
SailorCire

Reputation: 594

#include <mutex> in C++11 will do that. All you'll need to do is pass the file number to each part\program\thread

Do be aware of race conditions though.

Upvotes: 2

Related Questions