1

演習として、生産者と消費者の問題の解決策を実装したいと思います。配列 int[] バッファと、生産者と顧客をそれぞれシミュレートする 2 つのメソッド Produce() と Consume() と、両方のメソッドを非同期的に呼び出す 1 つの「Execute」メソッドがあるとします。

おそらく、実装によってデッドロックが発生しないかどうかをテストするためです。Produce と Consume を長時間 (100 万回など) 繰り返し、Execute でこれら 2 つのメソッドが終了するまで待機させてから (私の単体テストで)一定時間(おそらく1分)後に呼び出しが返されることを確認してください。しかし、実装に競合状態やデータ破損がないかどうかをテストするにはどうすればよいでしょうか?

4

1 に答える 1

1

チェックする必要があるのはデッドロックだけではありません。デッドロックは常にすぐに検出され、アプリが停止します。メッセージの紛失または重複は、より危険で潜行性があります。メッセージが重複していると、重複が発生したときよりもかなり後でアプリがクラッシュする可能性があり、重複が発生した場所とは異なるモジュール/スレッド/ブロックで発生する可能性が最も高くなります。このようなバグは絶対的な悪夢です。

キュー クラスをテストするとき、内部ランダム配列 [256] メンバーとチェックサムを使用して「メッセージ」クラスを作成します。最初にこれらのメッセージを 10000 個作成し、個々のチェックサムを「totalChecksum」し、それらへのポインターを「プール」キューにプッシュします。複数のプロデューサー (私は通常 32 個使用します) は、プール キューから *Message インスタンスをポップし、それらを別の「通信」キューにプッシュします。複数のコンシューマー (私は通常 16 個使用します) が *Message インスタンスを通信キューからポップし、それらをプール キューにプッシュします。

部屋を 5 分間温めた後、単純な GUI フォーム タイマーが、manualResetEvent を待機するようにプロデューサーに指示する volatile ブール値を設定することで、プロデューサーを停止します。Sleep(500) 後、10000 件のメッセージすべてがプール キューに戻る必要があり、GUI はプール キュー カウントが 10000 であることを確認し、ループ内で 10000 件のメッセージをポップし、totalChecksum を実行してプッシュバックし、最後に最初の totalChecksum と比較します。これが成功した場合、ブール値はリセットされ、MRE はプロデューサを再度実行するように信号を送ります。

このテストを一晩中、繰り返し実行します。障害が発生した場合、キューは目的に適合していません。

于 2013-02-13T08:02:48.093 に答える