如何判断QMutex是否被锁定?

时间:2011-12-30 19:14:33

标签: c++ qt qt4

有没有人知道如何检查并查看QMutex是否被锁定,而不使用该功能:

bool QMutex::tryLock()

我不想使用tryLock()的原因是因为它做了两件事:

  1. 检查并查看互斥锁是否已锁定。
  2. 如果没有锁定,请将其锁定。
  3. 出于我的目的,我对执行第二步(锁定互斥锁)不感兴趣。

    我只是想知道它是否被锁定。

5 个答案:

答案 0 :(得分:23)

根据定义,尝试锁定互斥锁是判断它是否被锁定的唯一方法;否则当这个虚函数返回时,你怎么知道互斥锁是否仍然锁定?它可能在函数返回时被解锁;或者更重要的是,如果不执行锁定它所需的所有缓存刷新和同步,你实际上无法确定它是否被锁定。

答案 1 :(得分:7)

好的,我猜我没有真正的方法可以在没有实际使用tryLock()的情况下做我想要的。

这可以通过以下代码完成:

bool is_locked = true;

if( a_mutex.tryLock() )
{
    a_mutex.unlock();
    is_locked = false;
}

if( is_locked )
{
    ...
}

正如您所看到的,它解锁了QMutex,“a_mutex”,如果它能够锁定它。

当然,这不是一个完美的解决方案,因为当它到达第二个if语句时,互斥锁的状态可能已经改变。

答案 2 :(得分:4)

也许一个QSemaphore有一张许可证? available()方法可以为您提供所需的信息。

答案 3 :(得分:1)

QMutex专为锁定和解锁功能而设计。某些自定义计数器可能会满足收集统计信息 尝试QSemaphore作为前面提到的@Luca Carion。

答案 4 :(得分:0)

static bool isLocked(const QBasicMutex *mut) {
  auto mdata = reinterpret_cast<const QBasicAtomicPointer<QMutexData> *>(mut);
  return mdata->load();
}

此代码应在Qt 5上运行,并且不会与互斥锁状态混淆。

每个QBasicMutex都保存一个(原子)指针(称为d_ptr),如果不拥有该指针,则为NULL;如果拥有但未经争议,则为特殊值;或者是指向平台相关结构的指针(在Unix上,这是基本上是一个pthread互斥体)(如果该互斥体是拥有和争用的。)

我们需要reinterpret_cast,因为d_ptr是私有的。

更多信息可以在这里找到:https://woboq.com/blog/internals-of-qmutex-in-qt5.html

一个合法的用例是验证互斥对象是否确实被锁定,例如,如果互斥对象是函数的前提条件。我建议为此使用Q_ASSERT(isLocked(...))

测试未锁定的互斥锁本质上是不安全的,因此不应完成。