【问题标题】:Upgrading boost::shared_lock to exclusive lock将 boost::shared_lock 升级为独占锁
【发布时间】:2011-09-11 12:44:57
【问题描述】:

谁能解释一下 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
        }
    }
}

如果我在升级之前使用 read.unlock() 解锁读锁,它不会死锁。但这似乎没有必要?

【问题讨论】:

    标签: c++ multithreading boost


    【解决方案1】:

    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
            }
        }
    }
    

    【讨论】:

    • 不幸的是我需要多个阅读器才能同时进入循环,所以我不能使用升级锁。感谢您的解释。
    猜你喜欢
    • 2020-04-29
    • 1970-01-01
    • 2014-08-11
    • 1970-01-01
    • 2013-01-01
    • 2011-01-25
    • 1970-01-01
    • 1970-01-01
    • 2013-07-11
    相关资源
    最近更新 更多