我的这个引用计数器,应当是不安全的?

jiandingzhe 2014-01-19 11:00:15
如果某对象被一个线程持有,这个线程解引用的时候,另一个线程引用某对象,似乎会产生不确定的效果?

class RefCounted
{
public:

RefCounted()
: count(0)
{
}

virtual ~RefCounted()
{
}

void ref()
{
count++;
}

void unref()
{
count--;
if (count == 0) delete this;
}

size_t get_ref_count()
{
return count;
}
protected:
size_t count;
};

inline void intrusive_ptr_add_ref(RefCounted* self)
{
self->ref();
}

inline void intrusive_ptr_release(RefCounted* self)
{
self->unref();
}
...全文
230 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
lm_whales 2014-03-02
  • 打赏
  • 举报
回复
引用 7 楼 jiandingzhe 的回复:
不过,计数加减是不是最好用原子操作?
原子操作也是一种同步手段适用于比较小的数据(通常跟寄存器的宽度一致). 比如引用计数
jiandingzhe 2014-01-20
  • 打赏
  • 举报
回复
引用 2 楼 wangdahu888 的回复:
肯定得加锁呀
感觉加锁也没用:初始一次的情况下,先减后加和先加后减有完全不一样的效果,前者会把对象释放掉。 只是不知道实际上会不会存在这种情况。
jiandingzhe 2014-01-20
  • 打赏
  • 举报
回复
引用 4 楼 lm_whales 的回复:
只要没有被delete 那么多线程同时持有同一个对象的时候, 至少会有两个引用计数。 这样,不会出现先减后加的问题。 因为1个线程,引用计数减的次数,等于曾经加的次数的时候。 就不会再加了,这个对象就和这个线程,没有关系了。 这样更没有办法减了。 1个线程,只要通过复制手段,得到共享对象,那么就会在该线程里增加一次引用计数 那么只有撤销该对象,或者撤销另一个共享对象(该对象也会增加一次引用计数)的时候,才会减计数。 所以同一个线程,减的次数,总会比加的次数少。 所以,对所有线程(同步以后),加的次数,至少等于减的次数。 当然,如果你的引用计数,胡乱使用,或者不同步那样就不同了。 那样的话,可能还没有加的时候,引用计数已经变成0了。 于是删除对象,就不可能共享对象了。
嗯……有道理。看来的确不太可能发生我设想的情况。 不过,计数加减是不是最好用原子操作?
zhuobattle 2014-01-20
  • 打赏
  • 举报
回复
引用 3 楼 jiandingzhe 的回复:
[quote=引用 2 楼 wangdahu888 的回复:] 肯定得加锁呀
感觉加锁也没用:初始一次的情况下,先减后加和先加后减有完全不一样的效果,前者会把对象释放掉。 只是不知道实际上会不会存在这种情况。[/quote] 看了你的类设计和函数调用,除了加锁, 你还要对控制持有这个类的对象的引用计数管理, 其实总体来讲,一旦引用计数,也就是没有一个类会对这个对象的析构负责,要 它自己负责,使用不当就会经常出现内存泄漏,野指针。
zhuobattle 2014-01-20
  • 打赏
  • 举报
回复
肯定要同步,否则你会碰到概率较低的crash,而且你们qa可能无法测试出来,
lm_whales 2014-01-20
  • 打赏
  • 举报
回复
只要没有被delete 那么多线程同时持有同一个对象的时候, 至少会有两个引用计数。 这样,不会出现先减后加的问题。 因为1个线程,引用计数减的次数,等于曾经加的次数的时候。 就不会再加了,这个对象就和这个线程,没有关系了。 这样更没有办法减了。 1个线程,只要通过复制手段,得到共享对象,那么就会在该线程里增加一次引用计数 那么只有撤销该对象,或者撤销另一个共享对象(该对象也会增加一次引用计数)的时候,才会减计数。 所以同一个线程,减的次数,总会比加的次数少。 所以,对所有线程(同步以后),加的次数,至少等于减的次数。 当然,如果你的引用计数,胡乱使用,或者不同步那样就不同了。 那样的话,可能还没有加的时候,引用计数已经变成0了。 于是删除对象,就不可能共享对象了。
  • 打赏
  • 举报
回复
肯定得加锁呀
lm_whales 2014-01-19
  • 打赏
  • 举报
回复
这个没有同步

5,530

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 模式及实现
社区管理员
  • 模式及实现社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧