1

このオブジェクトの前に c++ オブジェクトのミューテックスを(ロック解除せずに)ロックすることは、適切で安全な方法ですか? これは、このミリ秒で他のスレッドからオブジェクトが使用される可能性を保護するために行います (非常に低い確率)。delete

その後、メモリは割り当て解除されますか?それは良い習慣ですか?

例:

    ptr_to_delete->MUTEX.lock_writing(); // can not delete session if its already locked. (additational protection)
    ptr_to_delete->cleanup();
    delete ptr_to_delete;
4

2 に答える 2

3

「これは、このミリ秒でのオブジェクトの使用の可能性を他のスレッドから保護するために行います」。この場合、オブジェクトのミューテックスがロックされているかどうかは実際には問題ではありません。あるスレッドでオブジェクトを削除し、他のスレッドがまだ使用可能なオブジェクトへのポインタを持っている場合は、次のようになります。問題。

編集

それはまだ問題があります。piokucが言ったように、ある時点でミューテックスを解放して解放する必要があります。そうしないと、プログラムがリークします。

ワーカースレッドとクリーニングスレッドが同時にオブジェクトへのポインタを取得できる状況がまだあります。ワーカースレッドがオブジェクトを使用する前にクリーニングスレッドがオブジェクトを削除すると、未定義の動作(つまり、クラッシュ)が発生します。

ポインターの配列に対して、ロックされていない場合にのみポインターを返す(そして、戻る前にロックする)アクセサー関数を作成する必要があります。そうすれば、一度に1つのスレッドだけがポインターを持つことができ、ワーカースレッドがクリーニングスレッドによって削除されたポインターを取得/使用する可能性はありません。

于 2012-12-07T10:29:25.030 に答える
2

Pthreads にはlock_writing機能がないため、その機能を知らずにコードを確認することはできません。

ただし、pthread_mutex_destroyロックされているミューテックスを呼び出すのは未定義の動作です。したがって、オブジェクトのデストラクタがそのミューテックスを (明示的に、またはデータ メンバーのデストラクタの一部として) 破棄すると仮定すると、その前にミューテックスのロックを解除する必要があります。

正しい場所でロックを解除すれば、コードは正しいです。間違った場所でロックを解除すると、正しくありません。正確な場所がどこかはわかりません。

他のスレッドは、他のスレッドが配列とメモリからオブジェクトを削除するために取得できると同時に、配列からオブジェクトへのポインタを取得できます。「作業」スレッドは常にポインターを取得し、ミューテックスをロックし、いくつかの作業を行ってからミューテックスをロック解除し、ポインターを永久に失います。

1 つのオブジェクトだけでなく、データ構造全体を保護するためにミューテックスが必要になる場合があります。競合状態の可能性があるように私には思えます:

Thread 1                                Thread 2
                                    get pointer to object from data structure
get ptr from data structure
lock object
cleanup
unlock object
destroy object
                                    lock object (oops, it doesn't exist any more)
于 2012-12-07T11:19:47.597 に答える