私の C++ プロジェクトには、シングルトン クラスがあります。プロジェクトの実行中に、同じシングルトン クラスが 2 つの異なるスレッドから同時にアクセスされることがあります。その結果、シングルトン クラスのインスタンスが 2 つ生成されますが、これは問題です。
このような場合はどのように処理するのですか?
私の C++ プロジェクトには、シングルトン クラスがあります。プロジェクトの実行中に、同じシングルトン クラスが 2 つの異なるスレッドから同時にアクセスされることがあります。その結果、シングルトン クラスのインスタンスが 2 つ生成されますが、これは問題です。
このような場合はどのように処理するのですか?
それはシングルトンではありません:-)
いくつかのコードを示す必要があるかもしれませんが、基本的な問題は同期領域にあります。
正しく行われた場合、2 つのスレッドがクラスの 2 つのオブジェクトを作成する方法はありません。実際、エラーのあるクライアントがインテントを破壊できないように、クラス自体がシングルトンの性質が適用される場所である必要があります。
基本的な構造は次のようになります。
lock mutex
if instance doesn't exist:
instance = new object
unlock mutex
ミューテックス保護 (またはクリティカル コード セクション、または 2 つのスレッドがコードを同時に実行できないことを言語/ライブラリ レベルで保証できるその他の方法) のようなものがない場合、スレッド 1 がチェック間でスワップ アウトされる可能性があります。インスタンス化により、「シングルトン」の2つのインスタンスが可能になります。
そして、他の人が間違いなく示唆するように、シングルトンは悪い考えかもしれません。私は、すべての使い方が間違っているキャンプにいるわけではありません.通常の問題は、人々がそれらを「神の」オブジェクトとして扱うことです. それらには用途がありますが、多くの場合、より良い方法がありますが、ユースケースがわからないため、それを変更する必要があるとは言いません。
シングルトンが2つのコピーを取得する場合、ミューテックスで保護されていません。内部オブジェクトを取得/アクセス/設定するときにミューテックスをロックします。
私はあなたがこのようなことをしたと信じていますif(!_instance)_instance = new Singleton()
。そこには重要なセクションがあります。ミューテックスで保護する必要があります。
異なるスレッドで 2 つの異なるインスタンスを取得する場合は、何か問題があります。プロセスとは異なり、スレッドはメモリを共有します。そのため、1 つのスレッド (オブジェクト インスタンスなど) に割り当てられたメモリは、別のスレッドでも使用できます。
シングルトンは使用しないでください。これはよく知られているAnti-Patternです。
よく読んでください:
シングルトン: 1995 年以来、あなたが知らなかった問題を解決する
あなただけが知っている理由で、それでも永続化して先に進みたい場合は、次のようなスレッドセーフなシングルトン実装が必要です。
YourClass* YourClass::getInstance()
{
MutexLocker locker(YourClass::m_mutex);
if(!m_instanceFlag)
{
m_instance = new YourClass();
m_instanceFlag = true;
}
return m_instance;
}
は、通常使用されるミューテックスMutexLocker
のラッパー クラスです。これは、インスタンスの作成時にミューテックスをロックし、関数の終了時にミューテックスのロックを解除します。