2010-12-14 26 views
1

複数のスレッドが特定のログファイルにアクセスしたときに、同期を達成するためのサンプルコードを提供できます。クリティカルセクションオブジェクトの使用について聞いたことがありますが、同じセクションオブジェクトを使用する方法については明確ではありません。スレッド間のC++エラーログファイルの同期

+1

マルチスレッド(boost、Qt、...)のライブラリはありますか?どのような種類のログファイルを使用していますか?ちょうどfstreamやカスタムクラスですか? – Philipp

答えて

4

実装の詳細は、現在のプラットフォーム(Win32、Posix、...)と使用するライブラリ(QT、ブースト、...)によって異なります。しかし、一般的な考え方は同じで、使用できるプリミティブには同等のものがあります。

このseries of articlesは、さまざまなプラットフォームで利用可能なオプションと同等のものをよく理解しているはずです。これにより

あなたはCriticalSectionクラスを記述することができるはずです。

class CriticalSection 
{ 
    // System specific object 

public: 
    CriticalSection(); 
    ~CriticalSection(); 

    void Lock(); 
    void Unlock(); 
}; 

を次に、あなたのログファイルにデータを送信するために、あなたは、ロックを取得データを送信してからロックを解除します。

static CriticalSection gLogFileCS; 
static std::ofstream* gLogFilePtr; 

void SendLogMessage(const char* message) 
{ 
    gLogFileCS.Lock(); 
    gLogFilePtr->write(message); 
    gLogFileCS.Unlock(); 
} 

あなたはおそらく、あなたはそれで終わったときには、必ずCriticalSectionのロックを解除することを確認するために、RAIIを使用する必要があります。あなたは、CriticalSectionScopeLockクラスを作成

class CriticalSectionScopeLock 
{ 
    CriticalSection& CriticalSection_; 

public: 
    CriticalSectionScopeLock(CriticalSection& cs) 
    : CriticalSection_(cs) 
    { 
     cs.Lock(); 
    } 

    ~CriticalSectionScopeLock() 
    { 
     cs.Unlock(); 
    } 
}; 

、その後SendLogMessage機能はそのように書き換えることができます:

void SendLogMessage(const char* message) 
{ 
    CriticalSectionScopeLock lock(gLogFileCS); 
    gLogFilePtr->write(message); 
} 

これは、押したときに(あなたがロックを取るキューにメッセージを投稿することによって改善することができますそのキューにデータを書き込んでいる別のスレッドがある場合に発生します。これは、ディスクへの書き込みが現在のスレッドをブロックする可能性があるため、ロックの競合を減らします。また、同期リソースを保持している間にスレッドブロックを持つことは一般的には好ましくありません。

+0

非常に良い答え – patriiice