Reputation: 95
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
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
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
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
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