Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C+;中实现一个简单的多线程文件记录器+;? 为了了解C++中的多线程编程,我正在实现一个基本的多线程记录器。_C++_Multithreading - Fatal编程技术网

如何在C+;中实现一个简单的多线程文件记录器+;? 为了了解C++中的多线程编程,我正在实现一个基本的多线程记录器。

如何在C+;中实现一个简单的多线程文件记录器+;? 为了了解C++中的多线程编程,我正在实现一个基本的多线程记录器。,c++,multithreading,C++,Multithreading,我使用std::deque在文件记录器类中存储消息。 每次线程记录一条消息时;该消息被推到了deque的后面 在一个单独的线程中,FileLogger检查deque中是否有任何消息,如果有,则将它们写入文件 对deque的访问由互斥锁保护 为了便于从任何地方登录;记录器是作为单例实现的 因为实例是一个(静态)指针,指针不会改变;实例不必由互斥锁保护? 我的代码正确吗? // FileLogger.h: class FileLogger { public: static void init

我使用std::deque在文件记录器类中存储消息。 每次线程记录一条消息时;该消息被推到了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);
}
//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编程的最佳选择。请务必进行代码审查!少量的工作代码非常适合这样的事情。我在下面只回答了您的实际问题,尽管有一些简单的问题“多线程”或“线程安全”多线程模块将是一个为自己的目的使用多个线程的模块。线程安全模块是一个设计为在同一程序中从多个线程调用的模块。