3

我有一个函数,它是一个类的一部分,在这个函数中,在函数的开头有一个 mutex.lock,在它返回之前有一个 mutex.unlock。现在遇到了互斥锁卡在锁定状态的情况。如果此功能是我使用该互斥锁进行锁定和解锁的唯一地方,那么可能会执行此操作。该函数是从主线程和其他 1 或 2 个 QThread 调用的。

更新:问题是由于线程没有在函数调用之间休眠。也许缺乏睡眠真的很快重新锁定了互斥锁?您也可以调用 yieldCurrentThread();

4

4 回答 4

5

如果函数中抛出异常,unlock()最后可能不会执行。为了确保 QMutex 在这种情况下被解锁,您可以使用QMutexLocker对象进行锁定。该对象在被销毁时会自动解锁互斥锁,即使在异常后堆栈展开期间发生这种情况也是如此。

于 2010-01-22T23:19:41.833 回答
1

在 Mac OS XI 上,即使在 100% 正确的逻辑中,QMutex 也会挂起。我围绕 QMutex 进行了包装调用,它增加/减少了原子引用计数,并且 QMutex 挂在一个地方,引用计数表示没有持有的互斥锁。

这在 Qt3 中发生过一次,在最近的 Qt 中再次发生(4.6.2 或 4.7.0,我不记得了)。将 QMutex 替换为直接用于操作系统原语的自定义类 - 解决了问题。

但是请注意,在我的情况下,此问题仅发生在 OS X 上。在 Windows 上,相同的代码运行良好。

于 2011-02-23T18:01:23.793 回答
0

我的猜测是调用这个函数的其他线程之一仍然持有锁,并没有释放它,所以下一个试图进入那段代码的线程必须等到锁被释放。

锁定/解锁代码中是否有任何阻塞调用?

来自 Qt QMutex文档:

当你在一个线程中调用 lock() 时,其他尝试在同一个地方调用 lock() 的线程将阻塞,直到获得锁的线程调用 unlock()

于 2010-01-22T23:15:54.400 回答
0

互斥锁在从同一个 QThread 解锁后立即重新锁定,以至于主线程没有时间将其锁定回来。添加 sleep 或 yieldCurrentThread() 解决了问题

于 2010-01-27T02:58:32.867 回答