Ben*_*ves 7 c++ multithreading boost
有人可以解释一下boost :: upgrade_lock的正确用法.以下代码导致死锁
//Global
typedef boost::shared_mutex Mutex;
typedef boost::shared_lock<Mutex> ReadLock;
typedef boost::upgrade_lock<Mutex> UpgradeLock;
typedef boost::upgrade_to_unique_lock<Mutex> WriteLock;
Mutex sharedMutex;
//Multi threaded reader and writer
{
ReadLock read(sharedMutex);
for (int ii = 0; ii < vec.size(); ++ii) {
Element e = vec[ii];
if (e.needsUpdating()) {
UpgradeLock upgrade(sharedMutex);
WriteLock write(upgrade)
//Do stuff
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果我在升级之前用read.unlock()解锁读锁,它不会死锁.但似乎这不应该是必要的吗?
在boost::shared_mutex类(实现UpgradeLockable概念)中,单个线程不应尝试同时获取共享和可升级(或唯一)锁.在任何时候,UpgradeLockable都可以拥有N个共享锁(通过lock_shared)和1个可升级锁(通过lock_upgrade).可升级锁可以请求它成为一个唯一的锁,它会阻塞,直到它成为独占持有者,这需要释放所有共享锁.在不释放共享锁的情况下,无法从共享锁转换为唯一锁,或共享锁转换为可升级锁.
注意,可升级锁不是独占的(可以保持其他共享锁)只是它具有增加其强度的特殊权限.不幸的是,不允许同时使用多个可升级的线程.
在你的情况下,在同一个线程正在尝试使用lock_shared和lock_upgrade,这将死锁.您可以按如下所示重写它,它不会死锁,但它仍然是所有读者的单点争用,因为只有1将一次保持升级锁定.在这种情况下,根据您的其他功能,可能不需要shared_mutex的复杂性.但是,如果其他功能仍在获取共享锁,则下面的内容将按预期执行.
//Multi threaded reader and writer
{
// Only 1 thread can pass this. Other shared locks are also valid
UpgradeLock read(sharedMutex);
for (int ii = 0; ii < vec.size(); ++ii) {
Element e = vec[ii];
if (e.needsUpdating()) {
// Blocks here until all shareds are released
WriteLock write(upgrade)
//Do stuff
}
}
}
Run Code Online (Sandbox Code Playgroud)