我目前正在使用boost库实现读/写锁,而不使用shared_lock和unique_lock。我已经阅读了一些相关的问题(例如,How would a readers/writer lock be implemented in 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();
}问题是:
提前感谢您的友好帮助!
发布于 2015-05-05 07:11:52
如果使用notify_all,则多个线程可以重新获取相同的锁。
不是的。每个通知的线程都将以与相同的方式与竞争锁获取。即使使用notify_all,最多只能有一个线程执行关键部分的代码。因此,使用notify_all是完全正确的。
由于读从不阻止读取,任何读取线程都不能wait()其他读取线程。因此,即使使用当前代码,ReleaseReadLock()也只能通知写线程。
因此,在ReleaseReadLock()中,您可以安全地使用notify()而不是notify_all:没有理由唤醒所有写线程,因为只有其中一个线程可以锁定r/w锁。
至于其他优化,您最好修复这个答案中列出的人工制品:https://stackoverflow.com/a/12657243/3440745
https://stackoverflow.com/questions/30044381
复制相似问题