0

以下は、失敗している統合テストの疑似コードです。

[テスト]

void TestLogger()
    // Init static logger
    Logger.Init(pathToFile);

    // Create five threads that will call LogMessages delegate
    for i = 1 to 5 
    {
       Thread aThread = new Thread(LogMessages)
       aThread.Start(i);
    }

    // let threads complete their work
    Thread.Sleep(30000);

    /// read from log file and count the lines
    int lineCount = GetLineCount();

    // 5 threads, each logs 5 times = 25 lines in the log
    Assert.Equal(25, lineCount);


static void LogMessages( object data )
  // each thread will log five messages
  for i = 1 to 5 
  Logger.LogMessage(i.ToString() + " " + DateTime.Now.Ticks.ToString());
  Thread.Sleep(50);

テストを実行するたびに行数が変わるようです。行数は 23 行の場合もあれば 25 行の場合もあります。

コードを少し調べてみたところ、複数のスレッドが同時にログ ファイルにアクセスしていることに気付きました (ティック カウントが同じであることが確認されました)。このファイルへのアクセスにロックはありませんが、例外がスローされることはありません。実行間のログ行数が一貫していない理由を誰か説明できますか? さらに、これは複数のスレッドが同時に同じファイルに書き込むことの悪影響ですか?

4

4 に答える 4

5

ここにあるように、競合状態は予測できないことで有名です。正しく機能しない書き込みの数はわかりません。場合によっては、完全に正常に機能することもあります。はい、これは同期せずに複数のスレッドから同じファイルに書き込むことの悪影響です。

于 2012-07-05T17:36:47.487 に答える
1

通常、マルチスレッド ロギングは、ディスクに書き込む 1 つのロガー スレッドにログ エントリをキューに入れる (プロデューサー/コンシューマー キューをブロックする) ことによって実行されます。これにより、ロック時間が *log エントリをキューにプッシュするのにかかる時間まで短縮されます: ほとんど競合がありません。キューは、ディスクの遅延、ネットワークの遅延などを吸収します。

単純なロックを使用すると、すべての呼び出しスレッドでディスク/ネットワークの待機時間/遅延が発生します。

于 2012-07-05T20:25:47.380 に答える
1

Environment.TickCount で同時性を検証しようとすると、うまくいかないでしょう。約 15 ミリ秒 (IIRC) の精度しかないため、2 つのスレッドの値が同じである場合、実際にわかっているのは、それらが互いに最大 15 ミリ秒以内にログを記録していたことだけです。

Logger クラスがログ ファイルへのアクセスをロックしていれば、それで十分です。を介して同期オブジェクトを作成し、private static readonly object sync = new object();実行しますlock (sync) { ... open/read/write the file ... }。そうしないと、使用しているストリームの種類に関係なく、スレッド セーフに翻弄されることになります (ヒント: 一般に、それらはスレッド セーフではありません)。

于 2012-07-05T18:20:31.443 に答える
1

おそらく、これらの種類のプロデューサー/コンシューマー デッドロックやその他の競合状態を処理する最も簡単な方法は、組み込みの lock() を呼び出すことです。

lock(Logger){
 //use your logger here
}

これにより、他のスレッドが寄せ付けられなくなります。上で簡単に説明したように、同期ロック スタイルを使用することもできます。この男のサイトには、利用可能なすべてのオプション (および長所と短所) の良い例があります。

http://www.gavindraper.co.uk/2012/02/05/thread-synchronizationlocking-in-net/

幸運を。

于 2012-07-05T18:45:08.987 に答える