プロジェクトで Intel Parallel インスペクターを使用していたところ、次の警告が表示されました。
アプリケーション内の 1 つ以上のスレッドが別のスレッドのスタックにアクセスしました。これは、アプリケーションに 1 つ以上のバグがあることを示している可能性があります。
実際、スレッド間で共有されるスタックに割り当てられたオブジェクトがいくつかあります。なぜこれが問題なのかわかりません。ヒントはありますか?
プロジェクトで Intel Parallel インスペクターを使用していたところ、次の警告が表示されました。
アプリケーション内の 1 つ以上のスレッドが別のスレッドのスタックにアクセスしました。これは、アプリケーションに 1 つ以上のバグがあることを示している可能性があります。
実際、スレッド間で共有されるスタックに割り当てられたオブジェクトがいくつかあります。なぜこれが問題なのかわかりません。ヒントはありますか?
間違っているわけではありません。間違っている可能性があります。プログラムに追加の診断を提供する Intel Parallel Inspector のようなツールは、偽陽性と偽陰性の間でトレードオフを行う必要があります。報告された場合の偽陽性率) よりも、そうでない場合 (報告されていない場合の偽陰性率が高い)。
Valgrind は、正しいコードのエラーを通知できるツールの別の例です。
ここでの本当の問題は、「他のスレッドは何をしているのか?」ということです。「もしかしたらその関数から戻ってスタックフレームが無効になるかもしれない」と思うなら、あなたは間違った並列プログラミングをしています。マルチスレッドの動作に関する回答は、「たぶん」で修飾する必要はありません。そのスレッドをセマフォや条件変数で待機させたり、他のスレッドと結合させたりして、そのスレッドが戻らないようにした方がよいでしょう。
Pubby :「私の知る限り、それは非常に非効率的です。」
非効率的な唯一の理由は、複数のコアが同じキャッシュ ラインを変更する可能性があるためです。これは、他の種類の共有メモリで発生するのと同じ問題です。
Collin:スタック フレームが別のスレッドでも有効であることをどうやって知ることができますか?
複数のスレッドで何かを使用する場合は、ある種の同期メカニズムを使用して、無効な方法で変更されないようにします。この状況も例外ではありません。
H2CO3:そうですね、他人の家に入ってはいけない理由はありますか?
アナロジーで遊ぶなら、プロセスは家であり、各スレッドは家の中の人々です. Dave が家事のリストを自分の部屋に置いている場合、私はそのリストを見る必要があるたびに彼の部屋に行きます。彼がそれをやめたら、彼は私に言ったほうがいいです。
このプログラムの振る舞いが受け入れられるかどうかはスタイルの問題です。
これを想像してみてください。スレッドが実行中で、ローカル (スタック) 変数 (オブジェクト) を持つメソッドが呼び出されます。このオブジェクトを作業キュー (別のスレッドによって処理されるキュー) に追加します。
そのスレッドは、最初のスレッドによって追加された項目を取得し、最初のスレッドのスタック上のオブジェクトにアクセスします。
その間、最初のスレッドは何をしましたか? メソッドを終了し、そのスタック領域を解放した可能性があります。その解放されたスペースは、再利用される場合とされない場合があります。最初のスレッドのスタックにアクセスする 2 番目のスレッドは、タイミングと呼び出しグラフに応じて、正しく動作する場合と動作しない場合があります。
2 番目のスレッドがスタック変数を処理している間にスタック変数が存在することがわかっている場合は、安全に実行できます。たとえば、スレッド 1 がスタック変数をキューに入れ、スレッド 2 が処理の終了を通知するまでブロックする場合、それは安全な操作です。
エラーではなく警告が発行されるのは、これが正当な操作である場合とそうでない場合があり、アナライザーがそれを確認する方法がないためです。