优化读/写锁的实现
optimize the implementation of read/write locks
我当前正在使用boost库实现读/写锁,而无需使用sharone_lock和unique_lock。我已经阅读了一些相关问题(例如,在C 11中如何实现读者/作者锁?),但是我仍然想优化实现。
这是我的代码:
enum LockType { NO_LOCK, READ_LOCK, WRITE_LOCK, INC_LOCK };
boost::mutex mutex_;
boost::condition condition_;
LockType lock_;
size_t owner_count_;
void AcquireReadLock() {
mutex_.lock();
while (lock_ != NO_LOCK && lock_ != READ_LOCK){
condition_.wait(mutex_);
}
// if there is no lock, then acquire read lock.
if (lock_ == NO_LOCK) {
lock_ = READ_LOCK;
++owner_count_;
mutex_.unlock();
return;
}
else {
// if there is read lock, then still acquire read lock.
assert(lock_ == READ_LOCK);
++owner_count_;
mutex_.unlock();
return;
}
}
void AcquireWriteLock() {
mutex_.lock();
while (lock_ != NO_LOCK){
condition_.wait(mutex_);
}
// if there is no lock, then acquire write lock.
assert(lock_ == NO_LOCK);
lock_ = WRITE_LOCK;
mutex_.unlock();
return;
}
void ReleaseReadLock() {
mutex_.lock();
--owner_count_;
if (owner_count_ == 0) {
lock_ = NO_LOCK;
}
mutex_.unlock();
// is it correct to use notify_all?
condition_.notify_all();
}
void ReleaseWriteLock() {
mutex_.lock();
lock_ = NO_LOCK;
mutex_.unlock();
// is it correct to use notify_all?
condition_.notify_all();
}
问题是:
在释放锁时我是否应该使用Notify_all?根据该文档,一旦通知线程,它将重新锁定锁。如果使用notify_all,则多个线程可以重新出现相同的锁定。那会发生什么?并且线程在检查条件之前是否会获取锁(即锁_!= no_lock&& lock _!= read_lock)?
如何优化程序?显然,在发布读取锁定时,我们只需要通知尝试获取写锁的线程,因为读取从未阻止读取。那么如何实现这个想法?
事先感谢您的帮助!
- 发布锁时我是否应该使用Notify_all?根据该文档,一旦通知线程,它将重新锁定锁。如果使用notify_all,则多个线程可以重新出现相同的锁定。那会发生什么?并且线程在检查条件之前是否会获取锁(即锁_!= no_lock&& lock _!= read_lock)?
是的,在释放锁时,应使用Notify_all。所有条件_等待mutex_将一一唤醒,因为他们必须首先锁定sutex_(这是内部完成的条件_等待操作)。
- 如何优化程序?显然,在发布读取锁定时,我们只需要通知尝试获取写锁的线程,因为读取从未阻止读取。那么如何实施这个想法?
必须通知所有等待Mutex_的线程,因为某些写作线程可能会等待释放读取锁。
我希望这对您有帮助!
如果使用notify_all,则多个线程可以重新出现相同的锁。
否。每个通知线程都将竞争进行锁定获取,就像mutex_.lock()
一样。即使使用 notify_all ,最多可以在当时执行关键部分的代码。因此,使用notify_all是完全正确的。
- 如何优化程序?显然,在发布读取锁定时,我们只需要通知尝试获取写锁的线程,因为读取从未阻止读取。那么如何实施这个想法?
作为读取,永不封锁读取,没有读取线程可以 wait()
其他读取线程。因此,即使您当前的代码ReleaseReadLock()
也只能通知写线程。
因此,在ReleaseReadLock()
中,您可以安全地使用notify()
而不是notify_all
:没有理由唤醒所有写入线程,因为只有其中一个才能aqcuire aqcuire a l/w lock。
至于其他优化,您应该更好地修复手工艺品,在此答案中列出:https://stackoverflow.com/a/12657243/34440745
- C++:如果 std::atomic_flag 是唯一的无锁原子类型,如何在C++中实现无锁数据结构?
- 简单的读写锁
- 使用 std::atomic 实现无锁结构,Dtor 崩溃
- 优化读/写锁的实现
- 提升::Asio 写锁
- 如何使用c++11原子库实现seqlock锁
- 在磁盘上实现无锁数据结构
- 在 Boost 中实现旋转锁.需要示例
- 如何从更基本的同步原语中创建多读/单写锁
- 此用例是否需要读写锁
- 将地址和布尔值存储在一个单词中,以实现无锁双链表
- 实现写时复制
- 在线程内部函数上使用哪种保护方法(互斥,读写锁.)
- 使用原子实现票据锁会产生额外的mov
- 我们可以在socket Map上使用读写锁吗?
- tmultireadexexclusivewritesynchronizer将写锁降级为读锁时的行为
- 在ZeroMQ中实现无锁的多线程应用程序
- 在另一个函数中增强读/写锁
- 单个进程中有数千个读/写锁
- 如何在c++ 14中实现读/写锁