このように実装しても安全ですか?:
typedef shared_ptr<Foo> FooPtr;
FooPtr *gPtrToFooPtr // global variable
// init (before any thread has been created)
void init()
{
gPtrToFooPtr = new FooPtr(new Foo);
}
// thread A, B, C, ..., K
// Once thread Z execute read_and_drop(),
// no more call to read() from any thread.
// But it is possible even after read_and_drop() has returned,
// some thread is still in read() function.
void read()
{
FooPtr a = *gPtrToFooPtr;
// do useful things (read only)
}
// thread Z (executed once)
void read_and_drop()
{
FooPtr b = *gPtrToFooPtr;
// do useful things with a (read only)
b.reset();
}
どのスレッドが実際の解放を行うかはわかりません。ブーストshared_ptr
はこのような状況で安全にリリースしますか?
Boostのドキュメントによると、スレッドセーフshared_ptr
は次のとおりです。
インスタンスは、複数の
shared_ptr
スレッドによって同時に「読み取り」(const操作のみを使用してアクセス)できます。複数のスレッドによって同時に、さまざまshared_ptr
なインスタンスに「書き込み」(演算子=
やなどの可変操作を使用してアクセス)することができます。reset
私に関する限り、上記のコードは、上記のスレッドセーフ基準のいずれにも違反していません。そして、私はコードがうまく動くはずだと信じています。私が正しいか間違っているか誰かに教えてもらえますか?
前もって感謝します。
編集済み2012-06-2001:00UTC + 9
上記の擬似コードは正常に機能します。実装はshared_ptr
、複数のスレッドがそのインスタンスにアクセスしている状況で正しく機能することを保証します(各スレッドは、コピーコンストラクターを使用してインスタンス化された独自のインスタンスにアクセスする必要があります)。shared_ptr
上記の擬似コードでdelete gPtrToFooPtr
は、shared_ptr
実装が所有するオブジェクトを最終的にリリース(参照カウントを1つ落とす)する必要があることに注意してください(これはではないので適切な式ではありませんがauto_ptr
、誰が気にします;))。この場合、マルチスレッドアプリケーションでSIGSEGVが発生する可能性があることに注意する必要があります。