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?

+2


source to share


2 answers


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.

+1


source


Qt has a QPointer class that does this. Pointers are automatically set to 0 if what they point to is removed.



(Of course, this will only work if you are interested in integrating Qt into your project.)

0


source







All Articles