多线程代码中的文件I / O问题

leo*_*n22 0 c++ winapi multithreading critical-section

我使用来保护我的线程函数在类中,CRITICAL_SECTION并执行许多Send / Receive套接字操作,一切正常,但是如果线程正在向日志文件写入,就会遇到麻烦!

H

class ClassA
{
public:
    ClassA();    
    ~ClassA();

    void run();
    ...

private:
    CRITICAL_SECTION criticalSection;
    LogFiles *m_logFiles;
    ...
};
Run Code Online (Sandbox Code Playgroud)

cpp

ClassA::ClassA()
{
    m_logFiles = new LogFiles();
    InitializeCriticalSection(&criticalSection);
}

ClassA::~ClassA()
{
    delete m_logFiles;
    DeleteCriticalSection(&criticalSection);
}

void ClassA::run()
{
    EnterCriticalSection(&criticalSection); 

    // do some stuff
    m_logFiles->WriteToFile(message);
    // do some stuff
    m_logFiles->WriteToFile(message);

    LeaveCriticalSection(&criticalSection);
}
Run Code Online (Sandbox Code Playgroud)

日志文件不包含所有信息(仅包含来自例如4个线程中的2个线程的数据)或被覆盖的行(同时写入2个线程)!

所以我想我还必须确保LogFiles中的WriteToFile方法安全吗?

感谢您的帮助和/或示例!

Dre*_*all 5

因为CRITICAL_SECTION是实例变量,所以每个ClassA对象实际上都有其自己的独立互斥量。结果,锁定互斥锁的一个对象(也称为进入临界区)不会阻止任何其他对象对其私有互斥锁执行相同操作,并且公共日志文件资源完全不受保护。

您可以通过将CRITICAL_SECTION类设置为静态的或全局的并在程序启动期间将其初始化来解决此问题。

更好的选择可能是LogFiles该类维护其自己的CRITICAL_SECTION(甚至更好的是,为其管理的每个日志文件维护一个),并在WriteToFile()调用时让该函数在内部对其进行显式锁定/解锁(也就是输入/离开)。这样资源可以保护自己,而不是明确要求其用户这样做。因此,它将始终正确地运行,并且将减轻LogFile班级用户的负担。