这是否有联锁? C ++

时间:2012-09-17 21:06:02

标签: c++ multithreading concurrency thread-safety interlocked

请注意 - 这些版本适用于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行 - 繁荣。

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

e.g。对于析构函数中的引用计数对象,这样的工作

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

这里,参考计数器递减并自动测试零,然后只有当等于零时才释放数据。

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

编辑1:我需要根据评论澄清一点,并感谢您的回复。发布者不对订阅者的“释放内存”负责,因此不会泄露。在通知之后,发布者将通过删除已淘汰的订阅者来完成清理容器的循环。

现在至于订阅者自己。当他们分离时,他们只是在听取出版商的意见。他们自己将继续生活在静态物体中(这是我们要求的合同)。为什么?因为我们在通知期间无法承担锁定费用。唯一的另一个选择是使用Share_Ptr,由于将来版本化,决定不将其合并到此DLL中。

我创建了一个手写的shared_ptr,但后来我发现任何对未包含在资源管理类中的对象的引用都会陷入同样的​​陷阱,只是推动订阅者必须做出的“要求”一定不要在其所述订户的实施中引用任何悬空引用。

这让我们回过头来说,订阅者无法“发布”,目前所有将使用它的客户端都是静态对象。我们只是展望未来。一些用户是遗留应用程序,并且不容易引入enabled_shared_from_this等。

2 个答案:

答案 0 :(得分:3)

  

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

对于测试,是的,会有一种方法。你只想比较指针。

要打电话,我对此表示怀疑。你需要一个警卫,即一个关键部分。

答案 1 :(得分:0)

您可以使用“智能指针”策略来执行指针的延迟归零。只要有人对指针的引用(由互锁引用计数确定),保持指针有效;当计数变为零时,可以安全地为空。