标签: reference-counting

如何在使用shared_ptr时检测周期

shared_ptr是Boost库中的引用计数智能指针.

引用计数的问题在于它不能处理循环.我想知道如何用C++解决这个问题.

请不要这样的建议:"不要制作周期",或"使用weak_ptr".

编辑

我不喜欢只使用weak_ptr的建议,因为很明显,如果你知道你会创建一个循环,那么你就不会有问题.如果在运行时生成shared_ptrs,您也无法知道编译时会有一个循环.

所以,请自行删除使用weak_ptr的答案,因为我特别要求不要那些答案......

c++ garbage-collection reference-counting shared-ptr

21
推荐指数
4
解决办法
6589
查看次数

为什么Python将引用计数保持为False和True?

我正在查看hasattr内置函数的源代码,并注意到一些引起我兴趣的行:

Py_INCREF(Py_False);
return Py_False;

...

Py_INCREF(Py_True);
return Py_True;
Run Code Online (Sandbox Code Playgroud)

不是Py_FalsePy_True全球价值观?出于纯粹的好奇心,为什么Python保留这些变量的引用计数?

python reference-counting python-c-api

21
推荐指数
1
解决办法
1608
查看次数

初始化属性,点符号

在我的init方法中使用点表示法将retain属性初始化为nil是不是一个坏主意?

对于像这样的普通房产:

@property (nonatomic, retain) id foo;
Run Code Online (Sandbox Code Playgroud)

在我设置的init方法中说self.foo = nil.合成的方法首先释放或自动释放foo(不完全确定潜在的实施).被fooguaranted第一setter或getter调用之前是零?或者它会指向随机垃圾,除非我明确设置foo = nil没有点符号?

initialization properties reference-counting objective-c dealloc

20
推荐指数
1
解决办法
1万
查看次数

std :: shared_ptr中的最大引用计数是多少?如果你试图超过它会发生什么?

如果我们假设std::shared_ptr存储引用计数(我意识到标准不需要,但我不知道任何没有的实现),那个引用计数具有有限的位数,这意味着存在最大数量的支持的引用.这导致了两个问题:

  • 这个最大值是多少?
  • 如果你试图超过它会发生什么(例如,通过复制引用具有最大引用计数的对象的std :: shared_ptr)?请注意,std::shared_ptr声明了复制构造函数noexcept.

该标准是否对这两个问题都有所了解?常见的实现如何,例如gcc,MSVC,Boost?

c++ reference-counting shared-ptr c++11

20
推荐指数
3
解决办法
3847
查看次数

如何在C++中实现线程安全引用计数

如何在C++编程语言中在X86 CPU上实现高效且线程安全的引用计数系统

我总是遇到关键操作不是原子的问题,可用的X86 Interlock操作不足以实现引用计数系统.

以下文章介绍了此主题,但需要特殊的CPU指令:

http://www.ddj.com/architect/184401888

c++ multithreading atomic reference-counting

19
推荐指数
2
解决办法
2万
查看次数

19
推荐指数
1
解决办法
3151
查看次数

用于智能指针的抽象基类(intrusive_ptr) - 处理继承,多态,可克隆性和从工厂方法返回

要求

  1. 我正在写一个名为RCObject"引用计数对象"的类;
  2. 该类RCObject应该是抽象的,作为框架的基类(EC++ 3 Item 7);
  3. RCObject应禁止在堆栈上创建子类的实例(MEC++ 1 Item 27);

    [ 增加: ]

    [假设BearRCObject] 的具体子类

    [ C.E.这里表示编译错误]

    Bear b1;                        // Triggers C.E. (by using MEC++1 Item 27)
    Bear* b2;                       // Not allowed but no way to trigger C.E.
    intrusive_ptr<Bear> b3;         // Recommended
    
    Bear* bs1 = new Bear[8];                   // Triggers C.E.
    container< intrusive_ptr<RCObject> > bs2;  // Recommended
    intrusive_ptr_container<RCObject> bs3;     // Recommended
    
    class SomeClass {
    private:
        Bear m_b1;                 // Triggers …
    Run Code Online (Sandbox Code Playgroud)

c++ polymorphism inheritance boost reference-counting

19
推荐指数
1
解决办法
3038
查看次数

原子衰减比增量更贵吗?

在他的Blog Herb Sutter写道

[...]因为增加智能指针引用计数 通常可以优化为与优化shared_ptr实现中的普通增量相同- 在生成的代码中只是普通的增量指令,而不是围栏.

然而,减量必须是原子减量或等效物,它产生特殊的处理器存储器指令,这些指令本身更昂贵,并且最重要的是在优化周围代码时引起存储器栅栏限制.

该文是关于执行的shared_ptr,我不确定他的评论是否只适用于此或通常是这样.从他的表述我收集它一般.

但是当我想到它时,我只能想到"更加昂贵的减量",当if(counter==0)紧接着 - 这可能就是这种情况shared_ptr.

因此,我想知道原子操作++counter是否(通常)总是快--counter,或者只是因为if(--counter==0)...shared_ptr?一起使用?

c++ performance atomic reference-counting memory-fences

18
推荐指数
3
解决办法
907
查看次数

为什么垃圾收集者在解除分配之前会等待?

我有一个"为什么这样做?" 关于垃圾收集的问题(任何/所有实现:Java,Python,CLR等).当垃圾收集器不再处于任何范围内时,它会释放该对象; 指向它的引用数为零.在我看来,一旦引用数量达到零,框架就可以解除分配,但我遇到的所有实现都会等待一段时间,然后一次解除分配许多对象.我的问题是,为什么?

我假设框架为每个对象保留一个整数(我认为Python会这样做,因为你必须调用PyINCREFPyDECREF在C中为它编写扩展模块时;可能这些函数在某处修改了一个真正的计数器).如果是这样,那么它不应该花费更多的CPU时间来消除对象超出范围的时刻.如果现在每个对象需要x纳秒,那么以后每个对象需要x纳秒,对吗?

如果我的假设是错误的并且没有与每个对象关联的整数,那么我理解为什么垃圾收集等待:它必须走引用图以确定每个对象的状态,并且该计算需要时间.这样的方法比显式引用计数方法消耗更少的内存,但我很惊讶它更快或者是其他原因的首选方法.这听起来像是很多工作.

从编程的角度来看,如果对象在超出范围后立即释放,那将会很好.我们不仅可以依赖于在我们希望它们执行时执行的析构函数(其中一个Python陷阱是__del__在可预测的时间没有调用),但是对程序进行内存配置会变得更加容易. 这是一个由此引起的混淆的例子.在我看来,在deallocate-right-away框架中编程的好处是如此之大,以至于为什么我所听到的所有实现在解除分配之前都要等待.这有什么好处?

注意:如果遍历引用图只需要识别循环引用(纯引用计数不能),那么为什么不采用混合方法呢?一旦引用计数达到零,就释放对象,然后进行定期扫描以查找循环引用.在这样的框架中工作的程序员将有一个性能/决定论理由,尽可能地坚持非循环引用.它通常是可行的(例如,所有数据都是JSON对象的形式,没有父指针).这是流行垃圾收集器的工作原理吗?

garbage-collection reference-counting

18
推荐指数
3
解决办法
2498
查看次数

原子参考计数

我试图准确理解线程安全的原子引用计数是如何工作的,例如std::shared_ptr.我的意思是,基本概念很简单,但我真的很担心减法加上如何delete避免竞争条件.

Boost的这个教程演示了如何使用Boost原子库(或C++ 11原子库)实现原子线程安全的引用计数系统.

#include <boost/intrusive_ptr.hpp>
#include <boost/atomic.hpp>

class X {
public:
  typedef boost::intrusive_ptr<X> pointer;
  X() : refcount_(0) {}

private:
  mutable boost::atomic<int> refcount_;
  friend void intrusive_ptr_add_ref(const X * x)
  {
    x->refcount_.fetch_add(1, boost::memory_order_relaxed);
  }
  friend void intrusive_ptr_release(const X * x)
  {
    if (x->refcount_.fetch_sub(1, boost::memory_order_release) == 1) {
      boost::atomic_thread_fence(boost::memory_order_acquire);
      delete x;
    }
  }
};
Run Code Online (Sandbox Code Playgroud)

好的,所以我得到了一般的想法.但我不明白为什么以下情况不可能:

说refcount是当前的1.

  1. 线程A:原子地将refcount递减为0.
  2. 线程B:原子地将refcount递增到1.
  3. 线程A:调用delete托管对象指针.
  4. 线程B:将refcount视为1,访问托管对象指针... …

c++ multithreading atomic reference-counting c++11

17
推荐指数
2
解决办法
6086
查看次数