将boost :: shared_lock升级为独占锁

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()解锁读锁,它不会死锁.但似乎这不应该是必要的吗?

Dav*_*e S 9

boost::shared_mutex类(实现UpgradeLockable概念)中,单个线程不应尝试同时获取共享和可升级(或唯一)锁.在任何时候,UpgradeLockable都可以拥有N个共享锁(通过lock_shared)和1个可升级锁(通过lock_upgrade).可升级锁可以请求它成为一个唯一的锁,它会阻塞,直到它成为独占持有者,这需要释放所有共享锁.在不释放共享锁的情况下,无法从共享锁转换为唯一锁,或共享锁转换为可升级锁.

注意,可升级锁不是独占的(可以保持其他共享锁)只是它具有增加其强度的特殊权限.不幸的是,不允许同时使用多个可升级的线程.

在你的情况下,在同一个线程正在尝试使用lock_sharedlock_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)