为了了解C++中的多线程编程,我正在实现一个基本的多线程记录器。
每次线程记录一条消息时;该消息被推到了deque的后面。
在一个单独的线程中,FileLogger检查deque中是否有任何消息,如果有,则将它们写入文件。
对deque的访问由互斥锁保护。
为了便于从任何地方登录;记录器是作为单例实现的。
因为实例是一个(静态)指针,指针不会改变;实例不必由互斥锁保护?
我的代码正确吗?
// FileLogger.h:
class FileLogger
{
public:
static void initialize(const char* filePath) { // called by main thread before any threads are spawned
instance_ = new FileLogger(filePath);
}
static FileLogger* instance() { // called from many threads simultaneously
return instance_;
}
void log(const std::string &msg);
private:
FileLogger(const char* filePath);
void writeToFile();
static FileLogger* instance_;
std::deque<std::string> messages;
std::mutex messagesMutex; // lock/unlock this each time messages is pushed or popped
std::ofstream fout;
std::thread writerThread;
};
// FileLogger.cpp:
FileLogger* FileLogger::instance_ = nullptr;
void FileLogger::writeToFile() {
for (;;) {
std::string message;
while (messages.empty()) {
std::this_thread::sleep_for(std::chrono::nanoseconds(10));
}
messagesMutex.lock();
message = messages.front();
messages.pop_front();
messagesMutex.unlock();
fout << message << std::endl << std::flush;
}
}
FileLogger::FileLogger(const char* filePath) {
fout.open(filePath);
std::thread t(&FileLogger::writeToFile, this);
writerThread = std::move(t);
}
void FileLogger::log(const std::string &msg) {
std::lock_guard<std::mutex> lg(messagesMutex);
messages.push_back(msg);
}