2 つのケースがあります。
1 つのスレッドが共有データを所有する
スレッド 1 がオブジェクトの「所有者」であり、スレッド 2 がそれを使用する必要がある場合は、スレッド 2 に weak_ptr を格納します。弱いポインターは参照カウントに参加しません。代わりに、オブジェクトがまだ存在する場合にオブジェクトへの shared_ptr にアクセスする方法を提供します。オブジェクトが存在しない場合、weak_ptr は空/null の shared_ptr を返します。
次に例を示します。
class CThread2
{
private:
boost::weak_ptr<T> weakPtr
public:
void SetPointer(boost::shared_ptr<T> ptrToAssign)
{
weakPtr = ptrToAssign;
}
void UsePointer()
{
boost::shared_ptr<T> basePtr;
basePtr = weakPtr.lock()
if (basePtr)
{
// pointer was not deleted by thread a and still exists,
// so it can be used.
}
else
{
// thread1 must have deleted the pointer
}
}
};
この質問に対する私の回答 (リンク) も役に立つかもしれません。
データは両方が真に所有しています
あなたのスレッドのいずれかが削除を実行できる場合、私が上で説明したことはできません。両方のスレッドは、基になるオブジェクトに加えてポインターの状態を知る必要があるため、これは「ポインターへのポインター」が役立つ場合です。
boost::shared_ptr< boost::shared_ptr<T> >
または(生のptrを介して)
shared_ptr<T>* sharedObject;
あるいは単に
T** sharedObject;
なぜこれが役立つのですか?
- T へのリファラーは 1 つしかありません (実際、shared_ptr はかなり冗長です)。
- 両方のスレッドが単一の共有ポインタのステータスを確認できます (NULL ですか? 他のスレッドによって削除されましたか?)。
落とし穴: - 両側が同時に削除しようとするとどうなるかを考えてみてください。このポインターをロックする必要があるかもしれません。
改訂された例:
class CAThread
{
private:
boost::shared_ptr<T>* sharedMemory;
public:
void SetPointer(boost::shared_ptr<T>* ptrToAssign)
{
assert(sharedMemory != NULL);
sharedMemory = ptrToAssign;
}
void UsePointer()
{
// lock as needed
if (sharedMemory->get() != NULL)
{
// pointer was not deleted by thread a and still exists,
// so it can be used.
}
else
{
// other thread must have deleted the pointer
}
}
void AssignToPointer()
{
// lock as needed
sharedMemory->reset(new T);
}
void DeletePointer()
{
// lock as needed
sharedMemory->reset();
}
};
基礎となるデータの並行性の問題をすべて無視していますが、それはあなたが求めていることではありません。