I am working on a multithreaded logging for my engine. But I ma having troubles making it MT. The problem is, even if I am deep copying my logger object into a local variable I am going to have problems with the files. Because two threads are going to write to the same file at the same time which will build a mess. Here is my logger class:
class Logger {
public:
typedef std::vector<LogListener *> ListenerList;
private:
ListenerList listeners;
boost::mutex mutex;
public:
Logger();
~Logger();
Logger * write(const String &line);
};
Logger * Logger::write(const String &text) {
if(listeners.empty()) return this;
boost::unique_lock<boost::mutex> lock(mutex);
for(ListenerList::iterator i = listeners.begin(); i != listeners.end(); ++i) {
(*i)->write(text);
}
return this;
}
class FileLogListener : public LogListener {
std::ofstream stream;
public:
FileLogListener(const String &str) : stream(str.c_str(), std::ios::out | std::ios::app) { }
void write(const String &text) {
stream << text << std::endl;
}
};
Now suppose (avoiding mutexes):
//Thread 1
void func1() {
Logger * log = new Logger;
log->addListener("file.txt");
log->write("Thread 1 Test");
}
//Thread 2
void func2() {
Logger * log = new Logger;
log->addListener("file.txt");
log->write("Thread 2 test");
}
int main() {
boost::thread t1(&func1);
boost::thread t2(&func2);
t1.join();
t2.join();
return 0;
}
“file.txt” becomes a mess.
EDIT: Currently, I am reading and watching lectures on Multithreading to understand it better.
EDIT: The above logger works.
Thanks in advance,
Gasim Gasimzada
once I’ve written this article about minimalist logger. it’s a single header file simple logger that can be used in MT environment. it satisfied my logging needs in lots of projects
If you want to use your logger, you can just check the approach
in short: it just locks access to the file by boost::mutex