【双buffer无锁设计】

【双buffer无锁设计】
对于词典热加载等典型的“一写多读”场景,可以同过双buffer实现无锁切换新旧版本。
支持数据快照
• 为避免一条请求处理时前后数据不一致,会对全局数据做0拷贝快照, 只有在请求执行完成时才会更新数据

使用两个指针,一个指针指向当前使用的数据版本,所有读线程通过该指针读取数据,另一个是备份指针,写线程通过该指针写入,当写操作完成后对两个指针进行切换,完成数据更新。
直接切换会导致读线程获取到的数据失效,甚至可能访问的无效内存导致出core,因此通过智能指针封装这两个指针,当读指针的引用计数为1没有读线程使用时切换两个指针。
切换时会出现读写线程竞态因此需要加自旋锁。原因是切换操作的频率很低,而且临界区很小不会自旋太长时间。

对于同一请求会话里中途会不会出现指针切换导致前后数据不一致,可以将数据指针(智能指针)存放在Context对象里,从Context中取用数据。

双buffer大致实现:

template <class T>
class DualBuffer {
public:
  std::shared_ptr<T> GetPtr() const {
    LockGuard lock(lock_);
    return ptr_;
  }
  void ReloadBuffer() {
    ...//新数据写入 ptr_back_
    std::shared_ptr<T> old_ptr = GetPtr();
    {
    	LockGuard lock(lock_);
    	ptr_ = ptr_back_; //新数据可以被使用了
    }
    while (old_ptr.use_count() > 1) {
      ::usleep(10000);
    }
    // 没有读线程使用旧数据了
    ptr_back_ = old_ptr;
    ptr_back_->Clear();
  }
private:
  std::shared_ptr<T> ptr_;
  std::shared_ptr<T> ptr_back_;
  SpinLock lock_;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值