How to manage object lifetime with Boost library smart pointers?
There is a scenario I need to solve with shared_ptr and weak_ptr smart pointers.
The two threads, thread 1 and 2, share a common object named A. Each of the threads has a reference to this object. thread 1 decides to delete object A, but at the same time thread 2 can use it. If I used shared_ptr to store references to A's objects in each thread, the object won't get deleted at the right time.
What should I do to be able to delete an object when it is supposed to be and prevent the error in other threads that use that object at the same time?
source to share
There are 2 cases:
One thread owns shared data
If thread1 is the "owner" of an object and thread2 should just use it, store weak_process in thread2. Weak pointers do not participate in reference counting; instead, they provide a way to access the shared_ptr to an object if the object still exists. If the object does not exist, weak_ptr will return an empty / null shared_ptr.
Here's an example:
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
}
}
};
My answer to this question ( link ) might also be helpful.
The data really belongs as
If any of your threads can perform the delete, then you cannot have what I described above. Since both threads need to know the state of the pointer in addition to the underlying object, this might be a case where "pointer to pointer" is useful.
boost::shared_ptr< boost::shared_ptr<T> >
or (via raw ptr)
shared_ptr<T>* sharedObject;
or simply
T** sharedObject;
Why is this useful?
- You only have one referrer for T (actually shared_ptr is rather redundant)
- Both threads can check the state of a single shared pointer (is it NULL? Has it been removed by another thread?)
Pitfalls: - Think what will happen when both sides try to delete at the same time, you may need to lock this pointer
Revised example:
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();
}
};
I ignore all the concurrency issues with the underlying data, but that's not what you are asking for.
source to share