请注意-这些构建适用于VS2008 / VS2010构建,我不能使用任何11种构建。

想象一下,我有订阅者在听一些发布者。我的发布者有一个订户指针容器。在我的void detach(ISubscriber *)中,不是锁定订户列表,而是为该订户提供“空”字,因为缺少更好的单词。

//My container in the publisher.  Inserts to not invalidate, removals only invalidate iterators pointing to the removed element, for this reason we NULL
Container<ISubscriber *> myContainer;

Now in the publisher...
void NotifySubscribers(){
   foreach(subscriber in container){
      if(subscriber)//This is my problem
         subscriber->notify()
   }
}


第3行-测试了指针,并指向有效对象。
在执行第4行之前,另一个线程使订户为NULL。
第4行-景气。

我的问题是,有没有一种方法可以使用某种互锁的东西,使得测试和调用是原子的。

例如对于析构函数中的引用计数对象,类似这样的工作

 RefCountObject::~RefCountObject(){
    if(InterlockedDecrement(&m_count) == 0)
      delete m_data;
 }


在此,参考计数器会自动递减并针对零进行测试,然后且只有在等于零时,才释放数据。

有没有办法让我根据指针的有效性来调用函数?

编辑1:我需要根据评论澄清一下,并感谢您的答复。发布者不对订阅者的“释放内存”负责,因此不会泄漏。收到通知后,发布者将经历一个循环,该循环通过删除无效的订阅者来清理容器。

现在,关于订户本身。当他们分离时,他们只是从收听发布者中分离出来。它们本身将生活在静态对象中(这是我们需要的合同)。为什么?因为在通知期间我们无力持有锁。唯一的其他选择是使用Share_Ptr,由于将来的版本控制,因此决定不将其合并到此DLL中。

我创建了一个手写的shared_ptr,但是后来我想到,对未包装在资源管理类中的对象的任何引用都将陷入相同的陷阱,并只是推动订户必须确保不要求的“要求”在所述用户的实现中参考任何悬挂的参考。

让我们回到刚才说的那样,不能“释放”订阅者,并且当前将使用该订阅者的所有客户端都是静态对象。我们只是在展望未来。有些用户是旧版应用,因此不容易引入enabled_shared_from_this等。

最佳答案

有没有一种方法可以使用某种互锁的东西,使得测试和调用是原子的。


对于测试,是的,将有一种方法。您只想比较一个指针。

打电话,我对此表示怀疑。您将需要在电话周围保持警惕,即关键部分。

09-27 23:44