我正在尝试使用 shared_mutex 在 C++ 中使用读/写锁
typedef boost::shared_mutex Lock;
typedef boost::unique_lock< Lock > WriteLock;
typedef boost::shared_lock< Lock > ReadLock;
class Test {
Lock lock;
WriteLock writeLock;
ReadLock readLock;
Test() : writeLock(lock), readLock(lock) {}
readFn1() {
readLock.lock();
/*
Some Code
*/
readLock.unlock();
}
readFn2() {
readLock.lock();
/*
Some Code
*/
readLock.unlock();
}
writeFn1() {
writeLock.lock();
/*
Some Code
*/
writeLock.unlock();
}
writeFn2() {
writeLock.lock();
/*
Some Code
*/
writeLock.unlock();
}
}
代码似乎运行良好,但我有一些概念性问题。
Q1。我在 http://en.cppreference.com/w/cpp/thread/shared_mutex/lock 上看到了使用 unique_lock 和 shared_lock 的建议。 , 但我不明白为什么因为 shared_mutex 已经支持 lock 和 lock_shared 方法?
Q2。这段代码是否有可能导致写饥饿?如果是,那我怎样才能避免饥饿?
Q3。是否有任何其他锁定类我可以尝试实现读写锁?
最佳答案
Q1:互斥包装器的使用
建议使用包装器对象而不是直接管理互斥量,以避免代码被中断且互斥量未释放的不幸情况,从而使其永远处于锁定状态。
这就是RAII的原理.
但这只有在您的 ReadLock 或 WriteLock 是使用它的函数的本地时才有效。
示例:
readFn1() {
boost::unique_lock< Lock > rl(lock);
/*
Some Code
==> imagine exception is thrown
*/
rl.unlock(); // this is never reached if exception thrown
} // fortunately local object are destroyed automatically in case
// an excpetion makes you leave the function prematurely
在您的代码中,如果其中一个函数被中断,这将不起作用,因为您的 ReadLock WriteLock 对象是 Test 的成员,而不是设置锁定的函数的本地对象。
Q2:写饥饿
目前还不完全清楚您将如何调用读者和作者,但是,是的,存在风险:
- 只要读者处于事件状态,编写者就会被 unique_lock 阻塞,等待互斥量以独占模式获取。
- 但是只要wrtier在等待,新的读者就可以获得共享锁的访问权限,导致unique_lock进一步延迟。
如果你想避免饥饿,你必须确保等待的写入者有机会设置他们的 unique_lock。例如,在你的读者中添加一些代码来检查作者是否在设置锁之前等待。
Q3其他锁类
不太确定你在找什么,但我的印象是 condition_variable
您可能会感兴趣。但是逻辑有点不同。
也许,您也可以通过跳出框框的方式找到解决方案:也许有一种合适的无锁数据结构可以通过稍微改变方法来促进读者和作者的共存?
关于c++ - C++中读写锁的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35588833/