并发索引

本文探讨了在多线程环境中,如何实现并发的Latch读写模式,特别是在数据库索引管理中的应用。详细介绍了Reader-Writer Locks的实现,包括数据成员、构造析构函数以及读写锁的获取与释放。同时,提到了蟹行协议在并发Search、Insert操作中的应用,确保了并发操作的安全性。
摘要由CSDN通过智能技术生成
Latch的读写模式
  • 读模式:多个线程在同一时间能够读取相同的对象;如果一个线程获持有一个处于读模式的latch,另一个线程也能够获取该处于读模式的latch。
  • 写模式:只有一个线程能够获取该对象;如果有其他线程持有处于任意模式下的latch,则其他线程是不能够获得write latch的。
  • 相容性矩阵:
    latch读写模式的相容性矩阵

Latch的实现

Reader-Writer Locks
  • 允许多个并发读者
  • 必须管理读写队列来避免饿死
  • 可以在自旋锁的基础上加以实现

可以用互斥量和条件变量来实现rwlatch, 在src/include/common/rwlatch.h 中实现了 ReaderWriterLatch 类。

数据成员和构造析构函数

互斥量 mutex_ 来保护当前的读者个数reader_count_ (读者队列上最多有 UINT_MAX 个读者)和是否有写者进入writer_entered_。当可以获取wlatch或rlatch时,用条件变量 writer_reader_唤醒其他读写线程。需要注意的是析构函数在析构 mutex_ 变量的时候,先使用了 guard 进行保护;其次是成员变量的声明顺序。

using mutex_t = std::mutex;
using cond_t = std::condition_variable;
static const uint32_t MAX_READERS = UINT_MAX;
public:
  ReaderWriterLatch() = default;
  ~ReaderWriterLatch() {
    std::lock_guard<mutex_t> guard(mutex_); }
private:
 mutex_t mutex_;
 cond_t writer_;
 cond_t reader_;
 uint32_t reader_count_{
   0};
 bool writer_entered_{
   false};
 
获取读锁和释放读锁

获取读锁的时候,在第 6 行代码可以看到,当有写者进入或读者数量达到最大值时,新进入的读者会睡眠在条件变量 reader_ 上;释放读锁的时候在 18~21 行首先检查是否有写者进入,如果释放后当前读者数量为0,则通知其中一个写线程,然后在 22~25 行检查当前读者数量,很明显当有读者持有该读锁时,其他读者也可以轻易获取该读锁,当释放该读锁后当前读者数量等于 MAX_READERS - 1 时,才可能会有其他读线程等待,此时需要唤醒它们。

01  /**
02   * Acquire a read latch.
03   */
04  void RLock() {
   
05    std::unique_lock<mutex_t> latch(mutex_);
06    while (writer_entered_ || reader_count_ == MAX_READERS) {
   
07      reader_.wait(latch);
08    }
09    reader_count_++;
10  }
11
12  /**
13   * Release a read latch.
14   */
15  void RUnlock() {
   
16    std::lock_guard<mutex_t> guard(mutex_);
17    reader_count_--;
18    if (writer_entered_) {
   
19      if (reader_count_ == 0) {
   
20        writer_.notify_one();
21      }
22    } else {
   
23      if (reader_count_ == MAX_READERS - 1) {
   
24        reader_.notify_one()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值