首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >优化读写锁的实现

优化读写锁的实现
EN

Stack Overflow用户
提问于 2015-05-05 04:35:48
回答 1查看 345关注 0票数 2

我目前正在使用boost库实现读/写锁,而不使用shared_lock和unique_lock。我已经阅读了一些相关的问题(例如,How would a readers/writer lock be implemented in C++11?),但我仍然希望优化实现。

这是我的代码:

代码语言:javascript
复制
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();
}

问题是:

  1. 在释放锁时是否应该使用notify_all?根据文档,一旦一个线程被通知,它将重新获取锁。如果使用notify_all,则多个线程可以重新获取相同的锁。然后会发生什么呢?在检查状态之前,线程是否会获得锁(即lock_!=NO_LOCK && lock_!=READ_LOCK)?
  2. 如何优化程序?显然,在释放读锁时,我们只需要通知试图获取写锁的线程,因为read从不阻止读取。那么如何实现这一理念呢?

提前感谢您的友好帮助!

EN

回答 1

Stack Overflow用户

发布于 2015-05-05 07:11:52

如果使用notify_all,则多个线程可以重新获取相同的锁。

不是的。每个通知的线程都将以与相同的方式与竞争锁获取。即使使用notify_all,最多只能有一个线程执行关键部分的代码。因此,使用notify_all是完全正确的。

  1. 如何优化程序?显然,在释放读锁时,我们只需要通知试图获取写锁的线程,因为read从不阻止读取。那么如何实现这一理念呢?

由于读从不阻止读取,任何读取线程都不能wait()其他读取线程。因此,即使使用当前代码,ReleaseReadLock()也只能通知写线程。

因此,在ReleaseReadLock()中,您可以安全地使用notify()而不是notify_all:没有理由唤醒所有写线程,因为只有其中一个线程可以锁定r/w锁。

至于其他优化,您最好修复这个答案中列出的人工制品:https://stackoverflow.com/a/12657243/3440745

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30044381

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档