0

クラスでスレッド関数を保護CRITICAL_SECTIONし、多くの送受信ソケット アクションを実行し、すべて問題ありませんが、スレッドがログ ファイルに書き込みを行っていると、問題が発生します。

時間

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

    void run();
    ...

private:
    CRITICAL_SECTION criticalSection;
    LogFiles *m_logFiles;
    ...
};

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);
}

ログファイルには、すべての情報が含まれているわけではありません (たとえば、4 つのスレッドのうち 2 つのデータのみ)、または上書きされた行 (2 つのスレッドが同時に書き込まれた) です。

それで、LogFiles の WriteToFile メソッドも保護する必要があると思いますか?!

助けや例をありがとう!

4

2 に答える 2

5

CRITICAL_SECTIONはインスタンス変数であるため、各ClassAオブジェクトは事実上、独自の独立したミューテックスを持ちます。その結果、1 つのオブジェクトがミューテックスをロックしても (クリティカル セクションに入っても)、他のオブジェクトがそのプライベート ミューテックスに対して同じことを行うのを防ぐことはできず、共通ログ ファイル リソースは完全に保護されません。

これを修正するには、CRITICAL_SECTIONクラスを静的にするかグローバルにし、プログラムの起動時に初期化します。

クラスがLogFiles独自の CRITICAL_SECTION (または、管理するログ ファイルごとに 1 つ) を維持し、WriteToFile()関数が呼び出されたときに内部的に明示的にロック/ロック解除 (別名、enter/leave) するようにすることをお勧めします。このようにして、ユーザーに明示的に要求するのではなく、リソースがそれ自体を保護できます。したがって、常に正しく動作し、LogFileクラスのユーザーの負担が軽減されます。

于 2013-09-26T21:50:35.670 に答える