查询 std::mutex 的锁定状态

Posted

技术标签:

【中文标题】查询 std::mutex 的锁定状态【英文标题】:Query std::mutex for lock state 【发布时间】:2014-04-15 09:48:40 【问题描述】:

我有一种情况,我想做如下所示的事情,但似乎没有办法在不改变其状态的情况下查询互斥锁。我不希望someFunctionCalledRepeatedlyFromAnotherThread() 等待互斥锁在它被锁定时释放。它必须在执行一些替代操作后立即返回。我猜这个遗漏是为了安全,因为锁可能会在查询它和函数返回之间的时间内释放。就我而言,如果在doSomeAlternativeAction() 发生时释放锁,就不会发生坏事。我处于这种情况可能意味着我做错了什么,那么我应该如何改变我的设计?

class MyClass 

    std::mutex initMutex;
public:
    void someInitializationFunction()
    
        std::lock_guard<std::mutex> lock(initMutex);
        // Do some work
    

    void someFunctionCalledRepeatedlyFromAnotherThread()
    
        if (initMutex.isLocked()) 
        
            doSomeAlternativeAction();
            return;
        
        // otherwise . . .
        std::lock_guard<std::mutex> lock(initMutex);
        // carry on with work as usual
    

【问题讨论】:

您可能想使用std::mutex::try_lock。 。 . .但这会改变互斥体的状态。 @learnvst 但仅当互斥锁未锁定时,您的代码也会更改其状态。 【参考方案1】:

询问互斥锁的状态是没有用的:它现在可能已解锁,但当您有时间锁定它时,它可能已被锁定。所以它没有这样的方法。

但是,它确实有一个方法try_lock(),如果它没有被锁定,它会锁定它,如果它获得了锁则返回true,否则返回false。并且std::unique_lockstd::lock_guard 的更高级版本)可以选择调用它。

所以你可以这样做:

void someFunctionCalledRepeatedlyFromAnotherThread()

    std::unique_lock<std::mutex> lock(initMutex, std::try_to_lock);
    if(!lock.owns_lock())
    
        doSomeAlternativeAction();
        return;
    
    // otherwise ... go ahead, you have the lock

【讨论】:

【参考方案2】:

听起来你想使用 std::unique_lock 而不是 std::lock_guard。 try_lock 方法的工作方式类似于 Windows 上的 TryEnterCriticalSection,其中该函数将自动获取锁并在可以获取时返回“true”,或者如果无法获取锁(并且不会阻塞)则仅返回“false”。请参阅http://msdn.microsoft.com/en-us/library/hh921439.aspx 和http://en.cppreference.com/w/cpp/thread/unique_lock/try_lock。请注意,unique_lock 还有其他成员可用于尝试锁定,例如 try_lock_for 和 try_lock_until。

【讨论】:

以上是关于查询 std::mutex 的锁定状态的主要内容,如果未能解决你的问题,请参考以下文章

std::mutex 锁定的顺序

std::mutex 如何在不同的线程中解锁?

在不同的函数中锁定/解锁 std::unique_lock

为啥 OSX 上的 std::mutex 这么慢?

使用 boost strand 和 std::mutex

确保当前线程持有 C++11 互斥锁