【问题标题】:What happens if I ReleaseMutex() twice?如果我 ReleaseMutex() 两次会发生什么?
【发布时间】:2010-12-02 08:31:48
【问题描述】:

如果我在互斥锁已解锁时错误地调用 ReleaseMutex() 会发生什么,Microsoft 文档只字未提。

详情:

我正在尝试在无法访问编译器的情况下修复一些 Windows 代码。

我意识到 WinApi 互斥锁都是递归的,并且是引用计数的。如果我使用该功能,很明显额外的ReleaseMutex() 调用会过早地减少引用计数器。

但是,我正在查看的代码不会递归地使用互斥锁,因此引用计数永远不会高于“1”。它确实释放互斥锁的次数超过了必要的次数......那么会发生什么?引用计数是否为负数?它是否保持为零(解锁)并且只返回一个可忽略的错误?

(当然,这段代码在调用这些函数时实际上并不检查错误!)

【问题讨论】:

  • 这是一个非常糟糕的问题。即使我知道,“它在 WinXP 下检查”在 Win7 下也可能完全不同。所以你真的不应该这样做。 (注意:我认为它已被选中)
  • peejaybee,您应该将该评论升级为答案!
  • 上面链接的微软文档页面看起来很清楚:如果您在没有先获取互斥锁的情况下在互斥锁上调用 ReleaseMutex(),则调用将失败而没有任何副作用。也就是说,不依赖这种行为可能是明智的;相反,您应该确保您的代码始终将其互斥锁发布与其互斥锁获取相匹配。侮辱那些试图在他们自己的时间免费帮助你的人也是相当糟糕的形式。

标签: c++ multithreading winapi mutex


【解决方案1】:

peejay 在他的评论中提供了一个很好的链接到ReleaseMutex documentation。我相信文档中的这一行回答了您的问题:

ReleaseMutex 函数失败,如果 调用线程不拥有互斥锁 对象。

虽然没有明确说明,但我认为释放互斥锁(第一次)会导致调用线程不再拥有互斥锁对象。因此,第二次调用将简单地失败。这样的实现也很有意义,因为它可以很容易地检测到这种类型的错误(只需检查返回值)。

【讨论】:

  • "如果函数失败,返回值为零。"
  • 完整引用如下:“如果函数失败,返回值为零。要获取扩展错误信息,请调用 GetLastError。”那么,调用 GetLastError() 后,我如何才能将此错误情况与可能发生的其他错误区分开来?
  • @alex: GetLastError() 将针对不同的错误条件返回不同的值...您甚至可以使用FormatMessage 从错误代码中创建人类可读的消息。
  • 那么调用 ReleaseMutex() 两次是否安全?当我看到它忙碌并释放互斥锁时,我中止了我的进程,而不是等待它。析构函数稍后也会释放它。没事吧?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-18
  • 2016-07-11
  • 2021-09-06
  • 1970-01-01
  • 2012-02-17
相关资源
最近更新 更多