我有一个函数,它是一个类的一部分,在这个函数中,在函数的开头有一个 mutex.lock,在它返回之前有一个 mutex.unlock。现在遇到了互斥锁卡在锁定状态的情况。如果此功能是我使用该互斥锁进行锁定和解锁的唯一地方,那么可能会执行此操作。该函数是从主线程和其他 1 或 2 个 QThread 调用的。
更新:问题是由于线程没有在函数调用之间休眠。也许缺乏睡眠真的很快重新锁定了互斥锁?您也可以调用 yieldCurrentThread();
我有一个函数,它是一个类的一部分,在这个函数中,在函数的开头有一个 mutex.lock,在它返回之前有一个 mutex.unlock。现在遇到了互斥锁卡在锁定状态的情况。如果此功能是我使用该互斥锁进行锁定和解锁的唯一地方,那么可能会执行此操作。该函数是从主线程和其他 1 或 2 个 QThread 调用的。
更新:问题是由于线程没有在函数调用之间休眠。也许缺乏睡眠真的很快重新锁定了互斥锁?您也可以调用 yieldCurrentThread();
如果函数中抛出异常,unlock()
最后可能不会执行。为了确保 QMutex 在这种情况下被解锁,您可以使用QMutexLocker
对象进行锁定。该对象在被销毁时会自动解锁互斥锁,即使在异常后堆栈展开期间发生这种情况也是如此。
在 Mac OS XI 上,即使在 100% 正确的逻辑中,QMutex 也会挂起。我围绕 QMutex 进行了包装调用,它增加/减少了原子引用计数,并且 QMutex 挂在一个地方,引用计数表示没有持有的互斥锁。
这在 Qt3 中发生过一次,在最近的 Qt 中再次发生(4.6.2 或 4.7.0,我不记得了)。将 QMutex 替换为直接用于操作系统原语的自定义类 - 解决了问题。
但是请注意,在我的情况下,此问题仅发生在 OS X 上。在 Windows 上,相同的代码运行良好。
我的猜测是调用这个函数的其他线程之一仍然持有锁,并没有释放它,所以下一个试图进入那段代码的线程必须等到锁被释放。
锁定/解锁代码中是否有任何阻塞调用?
来自 Qt QMutex文档:
当你在一个线程中调用 lock() 时,其他尝试在同一个地方调用 lock() 的线程将阻塞,直到获得锁的线程调用 unlock()
互斥锁在从同一个 QThread 解锁后立即重新锁定,以至于主线程没有时间将其锁定回来。添加 sleep 或 yieldCurrentThread() 解决了问题