【问题标题】:Simple Read Write Lock简单的读写锁
【发布时间】:2019-03-20 16:40:35
【问题描述】:

我发现互联网上的许多读写自旋锁实现都不必要地复杂。我用c++写了一个简单的读写锁。

如果我遗漏了什么,谁能告诉我?

int r = 0;
int w = 0;

read_lock(void) 
{
     atomic_inc(r); //increment value atomically
     while( w != 0);    
}

read_unlock(void)
{
   atomic_dec(r); // Decrement value atomically
}
write_lock(void)
{
 while( (r != 0) && 
            ( w != 0))
  atomic_inc(w); //increment value atomically
}

write_unlock(void)
{
    atomic_dec(w); //Decrement value atomically
}

用法如下。

read_lock()
// Critical Section
read_unlock();

write_lock()
// Critical Section
write_unlock();

编辑:

感谢您的回答。 我现在将答案更改为原子等价物

【问题讨论】:

  • 它不是有效的 C++,而且它似乎假设像 w++ 这样的东西是原子的。
  • 您的计数器没有同步。这不是线程安全的。
  • 感谢您的链接。我会通过链接
  • 目前不是有效的 C++(函数没有返回类型)。但更糟糕的是,它不是惯用的 C++。这些是必须成对发生才能工作的 C 函数调用。有一个模式。此代码也不是异常安全的。除了有问题的和未定义的 atomic_*() 函数之外,write_lock() 中似乎还有一个错误

标签: c++ concurrency locking readwritelock


【解决方案1】:

如果线程同时访问rw,它们就会发生数据争用。如果 C++ 程序存在数据竞争,则程序的行为是未定义的。

C++ 标准不保证int 是原子的。即使我们假设访问int 的系统是原子的,operator++ 即使在这样的系统上也可能不是原子操作。因此,同步增量可能会“消失”。

此外,在write_lock 中的循环之后,另一个线程也可以在w 递增之前结束它们的循环,从而允许多个同时写入者——我认为这个锁应该防止这种情况。


最后,这似乎是一种实现自旋锁的尝试。自旋锁有优点也有缺点。它们的缺点是它们在阻塞时会消耗线程的所有 CPU 周期。这是对资源的高度低效使用,不利于电池使用时间,也不利于其他可能使用这些周期的进程。但如果等待时间短,它可能是最佳的。

【讨论】:

  • 感谢 eerorika 的回答。你是对的,这是自旋锁的实现。我已经编辑了帖子。自旋锁在操作系统中很有用,比如在无法睡眠的中断上下文中。
  • 如果我们使用一个所有单词操作都是原子的系统,那么 r++, w++ 可以是原子的吧?
  • @sysinit x86 具有原子增量指令,因此增量可以是原子的。但它也有非原子增量,效率更高。编译器没有理由选择使用带有int 的原子操作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-11
  • 2011-01-25
  • 1970-01-01
  • 2022-11-11
  • 2011-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多