请注意-这些构建是为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行之前,另一个线程将订阅者设为空。第四行--轰隆声。
我的问题是,有没有一种方法可以使用某种互锁的东西,以便测试和调用是原子的。
例如,对于析构函数中的引用计数对象,如下所示
RefCountObject::~RefCountObject(){
if(InterlockedDecrement(&m_count) == 0)
delete m_data;
}在这里,参考计数器被自动递减并针对零进行测试,然后且仅在那时,如果等于零,则释放数据。
有没有办法让我根据指针的有效性来调用函数?
编辑1:我需要在评论的基础上澄清一点,谢谢你的回复。发布者对订阅者的“内存释放”不负责,因此不会发生泄漏。在通知之后,发布者将经历一个循环,该循环通过删除空的订阅者来清理容器。
现在,至于订阅者本身。当他们分离时,他们只是脱离了对发布者的倾听。它们本身将存在于静态对象中(这是我们需要的契约)。为什么?因为我们不能在通知期间持有锁。唯一的另一种选择是使用Share_Ptr,由于将来的版本控制,决定不将其合并到此DLL中。
我创建了一个手写的shared_ptr,但后来我想到,任何对没有包装在资源管理类中的对象的引用都会落入相同的陷阱,只会推入“要求”,即订阅者必须确保在其所述订阅者的实现中不引用任何悬空引用。
这让我们回到刚才所说的,订阅者不能被“释放”,目前所有使用它的客户端都是静态对象。我们只是在展望未来。其中一些用户是遗留应用程序,不容易引入enabled_shared_from_this等。
发布于 2012-09-18 05:14:31
有没有一种方法可以让我使用某种互锁的东西,这样测试和调用就是原子的。
对于测试,是的,将会有一种方法。你只是想比较一个指针。
打个电话,我很怀疑。你需要在呼叫周围有一个守卫,即一个临界区。
发布于 2012-09-18 07:40:42
您可以使用“智能指针”策略对指针进行延迟清空。只要有人拥有对指针的引用(由互锁引用计数确定),就保持指针有效;当计数变为零时,可以安全地将其设为null。
https://stackoverflow.com/questions/12467105
复制相似问题