【问题标题】:Recursive mutex on Windows?Windows上的递归互斥锁?
【发布时间】:2012-10-11 07:01:26
【问题描述】:

据我了解,在 Windows 上 CRITICAL_SECTION 只能用作非递归互斥锁。要获得递归互斥锁,您必须使用 OpenMutex 和朋友。

但是,AFAIU、Win32 Mutex 不能与条件变量一起使用(InitializeConditionVariable 等)

有没有办法在 Windows 上结合使用递归互斥锁和条件变量?

【问题讨论】:

  • 你理解错了。关键部分(就互斥体而言)可以递归使用。

标签: windows mutex condition-variable recursive-mutex


【解决方案1】:

valdo 的评论是正确的。 CRITICAL_SECTION 递归的。这里引用 MSDN 的一段话:“线程拥有临界区所有权后,它可以对 EnterCriticalSection 或 TryEnterCriticalSection 进行额外调用,而不会阻塞其执行。”问题解决了。

【讨论】:

    【解决方案2】:

    那没有任何意义。从语义上讲,条件变量的意义在于您在等待时自动释放锁——从而允许其他线程获取锁来执行您正在等待的事情。但是,递归互斥体上的“释放”操作实际上可能不会解锁它,因此在释放后等待可能会死锁。您想要一种方法来执行此操作这一事实强烈表明您的设计或您对条件变量的理解存在问题。

    想一想——当一个在递归互斥锁上持有锁的函数调用一个获取第二个锁的函数然后调用睡眠函数时会发生什么?如果锁被释放,第一个函数的逻辑将中断,因为对象将在它持有锁时被修改。如果锁没有被释放,等待将死锁,因为它正在等待的事情永远不会发生,因为它持有另一个线程需要的锁才能让它发生。

    在不知道您是否已经锁定条件变量的情况下,没有明智的方法来使用它。如果你知道你是否有锁,就不需要递归锁功能。如果你知道你已经有一个锁,不要费心调用锁函数。如果你知道你还没有锁,即使它不是递归的,锁函数也可以正常工作。

    【讨论】:

    • 在我的用例中,对互斥体的递归访问仅在等待完成后才会发生。这样就没有问题了。
    • 由于您正在跟踪何时递归使用互斥锁以及何时不使用,因此您不需要递归互斥锁。当你递归使用它时,不要费心调用锁定/解锁函数。
    • 我必须将状态(递归与非递归)存储在某处。该存储本身必须能够抵抗多个线程的同时访问。那将意味着使用原子。等等太复杂了。如上所述,CRITICAL_SECTION 递归的,所以没问题。无论如何感谢您的帮助!
    • 该存储是特定于访问结构的线程,因此不存在同时访问的风险。
    • (一个线程要么在一个代码路径中,将或可能阻塞条件变量,或者它不是。不需要与其他线程协商。)
    猜你喜欢
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    • 2012-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-10
    • 1970-01-01
    相关资源
    最近更新 更多