【发布时间】:2011-12-30 19:14:32
【问题描述】:
有没有人知道如何在不使用函数的情况下检查 QMutex 是否被锁定:
bool QMutex::tryLock()
我不想使用 tryLock() 的原因是因为它做了两件事:
- 检查互斥锁是否被锁定。
- 如果未锁定,则将其锁定。
出于我的目的,我对执行第二步(锁定互斥锁)不感兴趣。
我只是想知道它是否被锁定。
【问题讨论】:
-
为什么 ::tryLock 锁定会困扰您?获得锁后即可解锁。]
有没有人知道如何在不使用函数的情况下检查 QMutex 是否被锁定:
bool QMutex::tryLock()
我不想使用 tryLock() 的原因是因为它做了两件事:
出于我的目的,我对执行第二步(锁定互斥锁)不感兴趣。
我只是想知道它是否被锁定。
【问题讨论】:
根据定义,尝试锁定互斥锁是判断它是否被锁定的唯一方法;否则当这个虚构的函数返回时,你怎么知道互斥锁是否仍然被锁定?函数返回时它可能已解锁;或者更重要的是,如果不执行所有必要的缓存刷新和同步来锁定它,您实际上无法确定它是否被锁定。
【讨论】:
好的,我猜如果不实际使用 tryLock(),就没有真正的方法可以完成我的要求。
这可以通过以下代码完成:
bool is_locked = true;
if( a_mutex.tryLock() )
{
a_mutex.unlock();
is_locked = false;
}
if( is_locked )
{
...
}
如您所见,它会解锁 QMutex,“a_mutex”,如果它能够锁定它。
当然,这不是一个完美的解决方案,因为当它到达第二个 if 语句时,互斥锁的状态可能已经改变。
【讨论】:
也许QSemaphore 有一个许可证? available() 方法可能会给你你所需要的。
【讨论】:
QMutex 专为锁定和解锁功能而设计。一些自定义计数器可能会满足收集统计信息。
试试前面提到的@Luca Carion 的 QSemaphore。
【讨论】:
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(...))。
测试未锁定的互斥体本质上是不安全的,不应进行。
【讨论】: