メモリを割り当てて共有ポインタに割り当てるスレッドAがあります。次に、このスレッドは他の3つのスレッドX、Y、Zを生成し、共有ポインターのコピーをそれぞれに渡します。X、Y、Zがスコープ外になると、メモリが解放されます。ただし、2つのスレッドX、Yがまったく同じ時点でスコープから外れ、参照カウントに競合状態があるため、2ずつデクリメントするのではなく、1回だけデクリメントされる可能性があります。そのため、新しい参照カウントが0に低下するため、メモリリークが発生します。X、Y、Zはメモリを読み取っているだけであることに注意してください。共有ポインタを書き込んだりリセットしたりしない。長い話を短くするために、参照カウントに競合状態があり、それがメモリリークにつながる可能性がありますか?
5 に答える
boost::shared_ptr
ロック(またはロックフリーアトミックアクセス)を使用して、参照カウントがアトミックに更新されるようにします(これがドキュメントページから明確でない場合でも)。マクロを定義することにより、シングルスレッドコードを記述している場合は、ロックの使用を構成できますBOOST_SP_DISABLE_THREADS
。
異なるスレッドからの複数の書き込みに関する問題について説明しているhttp://www.boost.org/doc/libs/1_42_0/libs/smart_ptr/shared_ptr.htm#ThreadSafetyshared_ptr
のドキュメントの例では、同じインスタンスで動作するスレッドについて説明していることに注意してください(shared_ptr
オブジェクトは例ではグローバルである可能性があります)、同じオブジェクトを指す異なるコピーではありません。shared_ptr
これは、の通常のユースケースですshared_ptr
。質問で示した例(共有オブジェクトを指すコピーに作用する)はスレッドセーフです。
いいえ、ドキュメントによると、これらの問題は発生しません。
異なる
shared_ptr
インスタンスは、複数のスレッドによって同時に「書き込み」(operator =やresetなどの可変操作を使用してアクセス)できます(これらのインスタンスがコピーであり、その下で同じ参照カウントを共有している場合でも)。
他のいくつかは、これが安全であることを説明するドキュメントへのリンクをすでに提供しています。
絶対に反駁できない証拠については、Boost Smartptrが実際に独自のミューテックスを最初からboost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp
(またはプラットフォームの対応するファイル)に実装する方法を参照してください。
ドキュメントには次のように書かれています。
異なるshared_ptrインスタンスは、複数のスレッドによって同時に「書き込み」(operator =やresetなどの可変操作を使用してアクセス)できます(これらのインスタンスがコピーであり、その下で同じ参照カウントを共有している場合でも)。
したがって、どのスレッドも他のスレッドのポインタオブジェクトにアクセスしない場合は、問題ないはずです。ドキュメントの例を見て、どの例があなたのケースに関連しているかを確認してください。
Boostの種類ではなく、TR1またはC ++0xshared_ptrにアップグレードするのが最善の方法です。それらはスレッドセーフでなければならないことが標準化されていると思います。