如何在C+;中实现一个简单的多线程文件记录器+;? 为了了解C++中的多线程编程,我正在实现一个基本的多线程记录器。
我使用std::deque在文件记录器类中存储消息。 每次线程记录一条消息时;该消息被推到了deque的后面 在一个单独的线程中,FileLogger检查deque中是否有任何消息,如果有,则将它们写入文件 对deque的访问由互斥锁保护 为了便于从任何地方登录;记录器是作为单例实现的 因为实例是一个(静态)指针,指针不会改变;实例不必由互斥锁保护? 我的代码正确吗?如何在C+;中实现一个简单的多线程文件记录器+;? 为了了解C++中的多线程编程,我正在实现一个基本的多线程记录器。,c++,multithreading,C++,Multithreading,我使用std::deque在文件记录器类中存储消息。 每次线程记录一条消息时;该消息被推到了deque的后面 在一个单独的线程中,FileLogger检查deque中是否有任何消息,如果有,则将它们写入文件 对deque的访问由互斥锁保护 为了便于从任何地方登录;记录器是作为单例实现的 因为实例是一个(静态)指针,指针不会改变;实例不必由互斥锁保护? 我的代码正确吗? // FileLogger.h: class FileLogger { public: static void init
// 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);
}
//FileLogger.h:
类文件记录器
{
公众:
静态void initialize(const char*filePath){//在生成任何线程之前由主线程调用
实例=新文件记录器(文件路径);
}
同时从多个线程调用静态FileLogger*实例()
返回实例;
}
无效日志(const std::string和msg);
私人:
文件记录器(常量字符*文件路径);
void writeToFile();
静态文件记录器*实例;
std::deque消息;
std::mutex messagesMutex;//每次推送或弹出消息时锁定/解锁此项
标准:流式流量计;
std::threadwriterThread;
};
//FileLogger.cpp:
FileLogger*FileLogger::instance_uz=nullptr;
void FileLogger::writeToFile(){
对于(;;){
std::字符串消息;
while(messages.empty()){
std::this_thread::sleep_for(std::chrono::纳秒(10));
}
messagesMutex.lock();
message=messages.front();
messages.pop_front();
messagesMutex.unlock();
fout以下假设(减少代码):
- 有一个指针(一个拿着你的单身汉的指针)
- 此指针只设置一次,然后保持不变
- 只有在设置指针之后,才会启动更多线程
在这种情况下,您不必同步对指针本身的访问。线程的启动已经起到了同步的作用:启动线程之前发生的所有写操作对线程内部运行的代码都是可见的。最好的方法不是自己做。有许多现成的解决方案,比您编写的更快、更安全te.举个例子。@MarekR OP说这是为了学习。至于这个问题,它更适合代码审查Logger并不是学习MT编程的最佳选择。请务必进行代码审查!少量的工作代码非常适合这样的事情。我在下面只回答了您的实际问题,尽管有一些简单的问题“多线程”或“线程安全”多线程模块将是一个为自己的目的使用多个线程的模块。线程安全模块是一个设计为在同一程序中从多个线程调用的模块。