How to manage object life time using Boost library smart pointers?

我是研究僧i 提交于 2019-12-24 01:54:49

问题


There is a scenario that i need to solve with shared_ptr and weak_ptr smart pointers.

Two threads, thread 1 & 2, are using a shared object called A. Each of the threads have a reference to that object. thread 1 decides to delete object A but at the same time thread 2 might be using it. If i used shared_ptr to hold object A's references in each thread, the object wont get deleted at the right time.

What should i do to be able to delete the object when its supposed to and prevent an error in other threads that using that object at the same time?


回答1:


There's 2 cases:

One thread owns the shared data

If thread1 is the "owner" of the object and thread2 needs to just use it, store a weak_ptr in thread2. Weak pointers do not participate in reference counting, instead they provide a way to access a shared_ptr to the object if the object still exists. If the object doesn't 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 useful.

The data is truly owned by both

If either of your threads can perform deletion, than you can not have what I describe above. Since both threads need to know the state of the pointer in addition to the underlying object, this may be a case where a "pointer to a pointer" is useful.

 boost::shared_ptr< boost::shared_ptr<T> >

or (via a raw ptr)

shared_ptr<T>* sharedObject;

or just

T** sharedObject;

Why is this useful?

  • You only have one referrer to T (in fact shared_ptr is pretty redundant)
  • Both threads can check the status of the single shared pointer (is it NULL? Was it deleted by the other thread?)

Pitfalls: - Think about what happens 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'm ignoring all the concurrency issues with the underlying data, but that's not really what you're asking about.




回答2:


Qt has a QPointer class that does this. The pointers are automatically set to 0 if what they're pointed at is deleted.

(Of course, this would only work if you're interested in integrating Qt into your project.)



来源:https://stackoverflow.com/questions/1492504/how-to-manage-object-life-time-using-boost-library-smart-pointers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!