2

スレッドに関する質問があり、スレッドに関する控えめなバックグラウンドと見なされるものがあります。

次の (単純化しすぎた) 設計と動作があるとします。

オブジェクト ObjectA - オブジェクト ObjectB およびメソッド MethodA() への参照があります。Object ObjectB - ObjectA、要素の配列 ArrayB、およびメソッド MethodB() への参照があります。

ObjectA は、ObjectB のインスタンス化を担当します。ObjectB.ObjectA は、ObjectB のインスタンス化子を指します。

これで、いくつかの条件が満たされるたびに、新しい要素が ObjectB.ArrayB に追加され、この要素 (ThreadB_x など) に対して新しいスレッドが開始されます。x は 1 から ObjectB.ArrayB.Length になります。このような各スレッドは、ObjectB.MethodB() を呼び出してデータを渡します。次に、データ処理のために ObjectB.ObjectA.MethodA() を呼び出します。

そのため、複数のスレッドが同じメソッド ObjectB.MethodB() を呼び出します。これらのスレッドが同時に呼び出す可能性は非常に高くなります。MethodB には、新しいオブジェクトを作成して初期化するコードがたくさんあるので、問題はないと思います。しかし、このメソッドは ObjectB.ObjectA.MethodA() を呼び出しますが、そこで何が起こっているのかまったくわかりません。私が得た結果に基づくと、明らかに何も問題はありませんが、それを確認したいと思います。

今のところ、ObjectB.ObjectA.MethodA() の呼び出しを ObjectB.MethodB() 内の lock ステートメントで囲みました。それは 100% 確実ではありません。しかし、各 ThreadB_x が ObjectB.MethodB() を何度も非常に高速に呼び出すとどうなるでしょうか? ObjectB.ObjectA.MethodA() が終了するのを待っている呼び出しのキューはありますか?

ありがとう。

4

1 に答える 1

0

情報が不足しているため、あなたの質問に答えるのは非常に困難です。いくつかのパラメータを挙げると、で費やされる平均時間、methodAスレッドごとにこのメソッドが呼び出される回数、プロセスに割り当てられるコアの数、OS スケジューリング ポリシーによって異なります。

すべてが等しい場合、スレッド数が無限に増加すると、2 つのスレッドが共有リソースへのアクセスを同時に要求する確率が 1 になる傾向があることは容易に想像できます。この確率は、共有リソースに費やした時間に比例して速くなります。その直感がおそらくあなたの質問の理由です。

マルチスレッド化の主な考え方は、効果的に同時に計算できるコードを並列化し、可能な限り競合を回避することです。あなたのセットアップでmethodAは、純粋でない場合、つまり. プロセスの状態を変更する可能性がある場合、または C++ の用語で、それを作成できない場合const、競合の原因になります (関数は、その本体で純粋な関数または定数を使用する場合にのみ純粋になることができることを思い出してください)。

共有リソースを処理する 1 つの方法は、コードで行ったようにミューテックスで保護することです。もう 1 つの方法は、その使用を非同期サービスに変えようとすることです。1 つのスレッドがそれを処理し、他のスレッドが計算のためにそのスレッドを要求します。実際には、リクエストの明示的なキューが作成されますが、これらのリクエストを実行しているスレッドは、その間に別の作業を自由に行うことができます。目標は、スレッドが再スケジュールされるたびに発生するスレッド管理時間とは対照的に、常に計算時間を最大化することです。

もちろん、常にそうできるとは限りません。の結果がmethodA強く順序付けられた計算チェーンに属する場合。

于 2013-03-04T13:56:39.080 に答える