【问题标题】:How to alter the recursive locking behaviour of Windows Mutex?如何改变 Windows Mutex 的递归锁定行为?
【发布时间】:2010-12-31 14:14:20
【问题描述】:

如果当前拥有锁的线程试图获取它,Windows Mutex 似乎允许再次(递归地)获取获取的锁。

但是,基于 posix 的 pthread 锁不允许这种行为。

是否有任何编译时宏或任何设置可以使 windows 互斥锁的行为方式与 pthread 互斥锁相同?

【问题讨论】:

    标签: c windows posix mutex


    【解决方案1】:

    您无法更改 Windows 互斥锁是递归的这一事实。虽然 Posix 线程默认不是递归的,但您可以使用 pthread_mutexattr_settype()PTHREAD_MUTEX_RECURSIVE 标志来实现。

    在 Windows 中锁定互斥锁实际上是一项非常昂贵的操作,并且最适合进程间同步。对于仅在单个进程中使用的互斥锁,通常使用临界区,但是这些也是可重入的。正如 nobugz 所说,您需要使用初始化为最大计数 1 的信号量来获得非递归同步。

    信号量对象就像一个特殊的计数器,可以跨线程(或进程,如果创建共享)原子地递增和递减。通过创建一个最大计数为 1 的行为,您可以获得所需的非递归行为。

    【讨论】:

    【解决方案2】:

    只要您在 Windows 中编程,请避免重新实现其 Mutex 的行为。它被同一个线程重入对于它定义的行为是绝对必要的。

    没有线程关联的同步对象是计数为 1 的信号量。使用 CreateSemaphore()。

    Fwiw,很奇怪你需要这种行为。听起来您正试图在多个地方不恰当地使用相同的同步对象。您可以使用信号量,但您将失去并发潜力。考虑改用多个互斥锁。

    【讨论】:

    • 实际上,我有这个与遗留代码相关的问题,我想在不改变大部分逻辑的情况下解决它。所以,想知道行为是否可以改变。我的代码应该在多个操作系统中工作,所以我希望行为在所有操作系统中保持相同。 “听起来你正试图在多个地方不恰当地使用同一个同步对象。” - 是的。这是负面情况的情况。我只是希望在负面情况下所有操作系统的行为都相同。感谢您的回复!
    • 好吧,使用增强信号量。多平台且不可重入。
    • 您可能希望使用非递归互斥锁来同步任务(例如实现 N 个任务之间的屏障)。此外,还有很多理由认为递归互斥锁有害并避免使用。
    【解决方案3】:

    我建议使用Read/Write locks (aka SRW)。像 Windows Mutex 一样,它们不是递归的。与临界区一样,它们很轻,如果空闲则不会调用内核 (Benchmarks)。

    【讨论】:

      【解决方案4】:

      看看'fast mutex'下的这篇文章。

      这些类型的互斥锁不能递归获取。

      当然,您必须研究如何在 C 中实现它们。

      【讨论】:

      • Fast Mutex 支持适用于驱动程序,而不是用户模式代码。
      猜你喜欢
      • 2021-04-17
      • 1970-01-01
      • 1970-01-01
      • 2019-02-06
      • 1970-01-01
      • 2021-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多