0

マルチプロセスプログラムにバグがあります。プログラムは入力を受け取り、即座に出力を生成します。ネットワークは関与せず、時間参照もありません。このバグの原因を突き止めるのが難しいのは、たまにしか起こらないということです。

常に実行すると、正しい出力と誤った出力の両方が生成され、識別可能な順序やパターンはありません。

何がそのような非決定論的な振る舞いを引き起こす可能性がありますか?役立つツールはありますか?初期化されていない変数が使用されている可能性があります。どうすればそれらを見つけることができますか?

編集:問題は解決しました 。競合状態を提案してくれた人に感謝します。私のデザインがこれを防ぐと確信していたので、私はそれを考えませんでした。問題は、「waitpid」の代わりに「wait」を使用したことでした。そのため、あるプロセスが幸運にも期待していたプロセスよりも前に終了した場合、正しい順序が乱れることがありました。

4

7 に答える 7

5

あなたはそれが「マルチプロセス」プログラムだと言います-あなたはもっと具体的にできますか?複数のプロセスを処理する方法の競合状態である可能性があります。

プロセスがどのように相互作用するかについて詳しく教えていただければ、いくつかの可能性を考え出すことができるかもしれません。Artemのデバッガーの使用に関する提案自体は問題ありませんが、デバッガーを導入すると、特に競合状態に関しては、状況が完全に変わる可能性があることに注意する必要があります。個人的にはロギングが大好きですが、それでもタイミングが微妙に変わることがあります。

于 2009-06-06T19:39:13.020 に答える
3

スケジューラー!

基本的に、複数のプロセスがある場合、それらは任意の奇妙な順序で実行できます。これらのプロセスが読み取りと書き込みの両方を行うリソースを共有している場合(ファイル、メモリ、またはある種のIOデバイス)、opsはあらゆる種類の奇妙な順序でインターリーブされます。簡単な例として、2つのスレッド(メモリを共有するスレッド)があり、両方がグローバル変数xをインクリメントしようとしているとします。

y = x + 1;
x = y

これらのプロセスを実行しますが、この方法でコードをインターリーブします

x=1と仮定します

P1:

y = x + 1

したがって、P1では、ローカルでスタック上にある変数yに対して、y = 2。次に、スケジューラが入ってP2を開始します

P2:

y = x + 1
x = y

xはまだ1でしたので、1が追加されました。x = 2

その後、P1は終了します

P1:

x = y

そしてxはまだ2です!xを2回インクリメントしましたが、1回しか取得しませんでした。そして、これがどのように発生するかわからないため、非決定論的動作と呼ばれます。

幸いなことに、あなたはシステムプログラミングで最も難しい問題の1つと、関数型言語の人々の多くの主要な戦いの叫びに出くわしました。

于 2009-06-06T19:42:36.867 に答える
3

ほとんどの場合、競合状態、つまり予測できないため、不適切に同期されたスレッドまたはプロセス間の相互作用を再現およびデバッグするのが困難です。

この場合の非決定論は、プロセス/スレッドおよびメモリアクセスのスケジューリングに起因します。これは、ネットワークトラフィックやユーザー入力など、実行するたびにプログラムのスレッドでさまざまな実際の実行シーケンスにつながる割り込みを絶えず引き起こす多数の外部要因の影響を受けるため、予測できません。

于 2009-06-06T19:45:03.350 に答える
2

多くのことが考えられます。メモリリーク、クリティカルセクションへのアクセス、閉じられていないリソース、閉じられていない接続などです。役立つツールは1つだけです。デバッガー、アルゴリズムを調べてバグを見つけてみてください。問題のある部分は、ここにスニペットを貼り付けることができ、私たちはあなたを助けようとします。

于 2009-06-06T19:34:45.167 に答える
2

基本から始めましょう...すべての変数にデフォルト値があり、使用する前にすべての動的メモリがゼロになっていることを確認してください(つまり、mallocではなくcallocを使用してください)。これにフラグを立てるコンパイラオプションがあるはずです(あいまいなコンパイラを使用している場合を除く)。

これがc++の場合(「c」フォーラムであることがわかっています)、オブジェクトの作成と初期化が変数の割り当てに遅れをとってしまうことがあります。たとえば、(シングルトンやグローバル変数のように)複数のスレッドで同時に使用されるスコープがある場合、これにより問題が発生する可能性があります。

if(!foo)Foo tmp = new Foo();

複数のスレッドが上記にアクセスしている場合、最初のスレッドはfoo = nullを検出し、オブジェクトの作成と割り当てを開始してから、を生成します。別のスレッドが入ってfoo!= nullを見つけたので、セクションをスキップしてfooの使用を開始します。

于 2009-06-06T23:01:02.083 に答える
1

より正確な答えを出すには、コードの詳細を確認する必要がありますが、簡潔に言うと、複数のプロセスまたは複数のスレッド間で調整するプログラムがある場合、スレッドの実行時の変数によって不確定性が追加される可能性があります。あなたの申請。基本的に、OSが行うスケジューリングにより、プロセスとスレッドが順不同で実行される可能性があります。環境とコードに応じて、OSが実行するスケジューリングにより、結果が大きく異なる可能性があります。詳細については、マルチスレッドを使用したアウトオブオーダー実行の詳細をグーグルで検索できます。それは大きなトピックです。

于 2009-06-06T19:39:09.883 に答える
0

「マルチプロセス」とは、マルチスレッドを意味しますか?このルーチンを実行する2つのスレッドがある場合

i = 1;
while(true)
{
    printf(i++);
    if(i > 4) i = 1;
}

通常、出力は次のようになります。

112233441122334411223344

しかし、実際には次のようなものが表示されます

11232344112233441231423

これは、各スレッドが異なるレートでCPUを使用するようになるためです。(スケジュールスケジュールの背後には非常に複雑なものがあり、その背後にある技術的なことを説明するには弱すぎます。)言うまでもなく、平均的な人の観点からのスケジュールはかなりランダムです。

これは、他のコメントで言及されている競合状態の例です。

于 2009-06-06T19:42:31.890 に答える