你怎么知道 QMutex 是不是被锁定?

Posted

技术标签:

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

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

bool QMutex::tryLock()

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

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

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

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

【问题讨论】:

为什么 ::tryLock 锁定会困扰您?获得锁后即可解锁。] 【参考方案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(...))

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

【讨论】:

以上是关于你怎么知道 QMutex 是不是被锁定?的主要内容,如果未能解决你的问题,请参考以下文章

你怎么知道使用JavaScript是否打开大写锁定?

qt多线程中怎样锁定一个指定的变量?

当你在更新某条数据时,怎么用SQL语句锁定而不让别人同时更新? 请知道的说下。 谢谢了

QT——QMutex(互斥量)

如何判断一行是不是被锁定?

怎么查看mysql表是不是被锁定