0

ポリモーフィックオブジェクトoと2つのスレッドT1とがありT2ます。

oの最も派生したクラスのデストラクタは、の終了を待ってT2から戻ります。

のいくつかの仮想関数を呼び出しているときにT1削除oしても安全ですか?(つまり、相互排除やその他の種類の同期メカニズムを使用しないことを意味します)T2o


呼び出された最初のデストラクタが完了する前であっても、(vtableへのポインタのように)delete変更が許可されていない限り、安全であると思います。oこれは本当ですか?

4

3 に答える 3

2

まず、これを避けることができれば、脆弱でエラーが発生しやすくなります。機能させることはできますが、コードを少し変更すると機能しなくなる可能性があります。

完全なオブジェクト デストラクタ内のブロックが他のスレッドの完了を待機することだけを行い、基本オブジェクトに仮想デストラクタがあるか、または完全なオブジェクトが直接破棄されると想定している場合は、そうしても安全です。オブジェクトのメンバーは、デストラクタの本体が完了する前に破棄されず、ベースも破棄されません。つまり、他のスレッドが使用しているサブオブジェクトは、それが完了する前に破棄されることはありません (そして、最初のスレッドがデストラクタの本体を完了できるようにします)。

そうは言っても、コードを再設計してみてください。

于 2012-09-17T03:59:55.527 に答える
0

クラスに動的に割り当てられたメンバーがいくつかあるシナリオを想像してみてください。
T1のデストラクタは、これらのメンバーにT2アクセスしているときに、これらのメンバーの割り当てを解除する場合があります。
これにより、未定義の動作が発生します。

T1のデストラクタとの関数が同じメンバーで動作していないことを確認できる限りT2、安全ですが、確認できない場合は、必ず同期が必要です。

基本的なロジックは同じままであることに注意してください。同じエンティティで2つのスレッドが同時に読み取りと書き込みを行うことはできません。そうしないと、競合状態と同期の問題が発生します。

于 2012-09-17T03:21:57.760 に答える
0

前述のように、これは危険ですが、リスクを軽減するためにいくつかの手順を実行できます。スレッド同期の責任は、最も派生したクラスの単一の責任である必要があります。特に、この最も派生したクラスは、デストラクタ以外の仮想関数を持つべきではありません。

この設計は、T2 が最も派生したクラスの関数を呼び出すことができないことを意味します。せいぜい の基本クラスのメンバーに依存することができo、それらは最も派生した dtor が戻るまで有効です-これは T2 が終了した後です。つまり、ステップ 2 と 3 (無害) を除いて、次のシーケンスは並べ替えられないことを意味します。

  1. T2の基底クラスのメソッドにアクセスできますo
  2. スレッドT1では、 の dtoroが入力されます
  3. スレッドT2が終了します。
  4. threadT1では、 の dtor がo返されます
  5. の基本クラス メソッドはo呼び出せなくなりました。
于 2012-09-17T12:36:41.047 に答える