gpt4 book ai didi

c++ - Poco RefCountedObject 线程安全吗?

转载 作者:行者123 更新时间:2023-11-28 05:34:02 25 4
gpt4 key购买 nike

Poco RefCountedObject 提供 2 个接口(interface):

    inline void RefCountedObject::duplicate() const
{
++_counter;
}


inline void RefCountedObject::release() const throw()
{
try
{
if (--_counter == 0) delete this;
}
catch (...)
{
poco_unexpected();
}
}

与:

class Foundation_API RefCountedObject
/// A base class for objects that employ
/// reference counting based garbage collection.
///
/// Reference-counted objects inhibit construction
/// by copying and assignment.
{
public:
RefCountedObject();
/// Creates the RefCountedObject.
/// The initial reference count is one.

void duplicate() const;
/// Increments the object's reference count.

void release() const throw();
/// Decrements the object's reference count
/// and deletes the object if the count
/// reaches zero.

int referenceCount() const;
/// Returns the reference count.

protected:
virtual ~RefCountedObject();
/// Destroys the RefCountedObject.

private:
RefCountedObject(const RefCountedObject&);
RefCountedObject& operator = (const RefCountedObject&);

mutable AtomicCounter _counter;
};

请注意:可变的 AtomicCounter _counter;

我的问题是如果我在多线程中使用 RefCountedObject 是否安全?

在我看来,这并不是因为只有 --_counter 是原子的,而 if(--_count) 不是原子的,并且可能导致引用已删除的对象。例如假设我有 2 个线程 A 和 B,一个执行复制,另一个执行释放,执行顺序如下:

  • B开始执行release并到达--_counter
  • A开始执行duplicate并到达++_counter
  • 此时_counter=1
  • B 执行 --_counter 并返回 if 评估的结果(即 0 && counter 现在为 0)
  • B 被抢占并在分支语句(if)之前停止
  • A 执行 _counter++ 并返回对象的引用
  • B 继续计算值为 0 的分支语句并删除对象

我们最终得到 A 引用了一个已删除的对象。即使 mutable 关键字强制编译器不优化 _counter,它也无助于多线程

我错过了什么吗?

最佳答案

严格孤立地看重复和发布,以上是正确的。

但是,如果您有两个线程,它们都有一个指向同一个 RefCountedObject 的指针,那么您应该在每个线程中有单独的 AutoPtr 实例(这意味着开始时 _counter > 1),或者,如果您共享相同的AutoPtr,如果至少有一个线程可以更改 AutoPtr(这将导致调用 release()),则它必须由互斥体保护。不用说,在多个线程之间共享一个可变的 AutoPtr 是灾难的根源。

如果您通过手动调用 duplicate() 和 release() 来管理 RefCountedObject(我不推荐这样做),您应该遵循 POCO 的引用计数规则并非常小心。

因此,对于行为良好的代码,RefCountedObject 和 AutoPtr 对于多线程使用是安全的。

关于c++ - Poco RefCountedObject 线程安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38749500/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com