【问题标题】:How can you tell if a QMutex is locked or not?你怎么知道 QMutex 是否被锁定?
【发布时间】:2011-12-30 19:14:32
【问题描述】:

有没有人知道如何在不使用函数的情况下检查 QMutex 是否被锁定:

bool QMutex::tryLock()

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

  1. 检查互斥锁是否被锁定。
  2. 如果未锁定,则将其锁定。

出于我的目的,我对执行第二步(锁定互斥锁)不感兴趣。

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

【问题讨论】:

  • 为什么 ::tryLock 锁定会困扰您?获得锁后即可解锁。]

标签: c++ qt qt4


【解决方案1】:

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

【讨论】:

  • -1 小注意,有时在不干扰线程的情况下知道互斥体是否被锁定而不尝试锁定它是有用的,例如用于统计目的。因此,尽管您很重要,但这并不是“根据定义判断它是否被锁定的唯一方法”
  • 呃,有用的东西并不意味着根据定义它不是不可能的。
  • -1 这可能是不可能的,但对问题没有帮助,尽管此信息是真实的,但其他答案更有帮助。
【解决方案2】:

好的,我猜如果不实际使用 tryLock(),就没有真正的方法可以完成我的要求。

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

bool is_locked = true;

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

if( is_locked )
{
    ...
}

如您所见,它会解锁 QMutex,“a_mutex”,如果它能够锁定它。

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

【讨论】:

    【解决方案3】:

    也许QSemaphore 有一个许可证? available() 方法可能会给你你所需要的。

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:
        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 mutex) 如果互斥锁被拥有和竞争。

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

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

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

        测试未锁定的互斥体本质上是不安全的,不应进行。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-11-01
          • 2011-05-01
          • 2023-03-23
          • 2011-11-18
          • 2015-05-14
          • 2011-11-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多