8

C++に1つのフィールドを持つ単純なクラスAがあると仮定します。このフィールドはコンストラクターで初期化されます。クラスAには、doit()このフィールドの値を変更するために呼び出されるメソッドもあります。doit()複数のスレッドから呼び出されます。メソッドにのみミューテックスがある場合doit()、これで十分ですか?初期化されていないフィールドを読み取らないという保証はありますか(コンストラクターにロックがないため)?

編集:私はおそらく十分に明確ではありませんでした。プロセッサキャッシュなどに問題はありませんか?つまり、メモリ領域(つまり私のフィールド)を初期化するためのミューテックスがない場合、他のスレッドがガベージ値を読み取るリスクはありませんか?

4

3 に答える 3

7

オブジェクトは一度だけ初期化でき、初期化される前は使用できないため、そこでミューテックスは必要ありません。DoItただし、これは複数のスレッドを介してアクセスされると述べたように、関数にはミューテックスまたはその他の適切なロックが必要です。

編集された質問の更新:いいえ、プロセッサキャッシュについて心配する必要はありません。オブジェクトを処理する前に、まずオブジェクトを作成する必要があります。このハンドルを取得して初めて、他のスレッドに渡して使用することができます。私が言おうとしているのは、スポーンされたスレッドは元のオブジェクトの構築後に開始する必要があるということです。その逆は不可能です。

于 2012-10-12T10:42:33.263 に答える
2

まだ作成されていないオブジェクトを呼び出すことdoit()はできないため、コンストラクターにミューテックスは必要ありません。

がフィールドにアクセスする唯一の方法である場合doit()は、問題ないはずです。

クラスの他のメソッドも、単一のスレッドからでもそのフィールドにアクセスする場合は、これらのメソッドでもミューテックスを使用する必要があります。

于 2012-10-12T10:45:41.123 に答える
0
  1. それらの厄介なスレッドがオブジェクトを手に入れる前に、まずオブジェクトを構築する必要があります。OSは、1つのスレッドによってのみ呼び出されるコンストラクターにメモリを割り当てます。このOSはその割り当てを管理するため、ユーザー側で何もする必要はありません。同じクラスの2つのオブジェクトを2つの異なるスレッドで作成することもできます。
  2. あなたは非常に保守的であり、そのフィールドを使用してロックし、それを解放して終了するメソッドの開始時にミューテックスを使用することができます。

または、さまざまなメソッドとさまざまなアルゴリズムとの相互作用を理解している場合は、そのフィールドを使用するコードのクリティカルセクションにミューテックスを使用できます。つまり、コードのその部分では、フィールドが別のスレッドによって変更されていないことを確認する必要があります。処理しますが、メソッドはクリティカルセクションの後でロックを解放し、何か他のことをしてから、おそらく別のクリティカルセクションを持つことができます。

于 2012-10-12T12:11:37.583 に答える