互斥体上的 CloseHandle,在 ReleaseMutex 之前 - 会发生啥?

Posted

技术标签:

【中文标题】互斥体上的 CloseHandle,在 ReleaseMutex 之前 - 会发生啥?【英文标题】:CloseHandle on a Mutex, before ReleaseMutex - What happens?互斥体上的 CloseHandle,在 ReleaseMutex 之前 - 会发生什么? 【发布时间】:2011-02-17 20:38:03 【问题描述】:

如果我在线程完成互斥锁之前在互斥锁上调用 CloseHandle,因此尚未调用 ReleaseMutex,预期的行为是什么?

【问题讨论】:

这样做的原因是什么? @San Jacinto:MTA COM 对象的线程正在执行工作,并且调用 CoFreeUnusedLibraries(0, 0) 的调用者没有给时间,延迟为 0,它调用 DllCanUnloadNow,它返回 S_OK ,即使互斥锁尚未释放。 MTA 的延迟默认为 10 分钟以允许线程完成,但在这种情况下,我必须检查互斥体以确保其为 NULL,否则从 DllCanUnloadNow 返回 S_FALSE。这停止了​​我们遇到的内存访问冲突。现在,等待互斥体 == NULL 的问题在于,没有任何东西明确地调用 CloseHandle。 哇,很酷的解释。我可以建议您编辑您的问题以包含这些信息以供未来用户使用吗? @San Jacinto 我会尽快喘口气……关键时刻。 【参考方案1】:

CloseHandle() 立即销毁传递给它的句柄。如果使用关闭的互斥体句柄调用 ReleaseMutex(),则会失败并返回 ERROR_INVALID_HANDLE 错误代码。

如果互斥体被命名,则有一个单一的引用计数内核对象支持互斥体,但CreateMutex()OpenMutex() 返回必须单独关闭的唯一HANDLE 值。如果创建/打开同名互斥锁的多个句柄,则在一个句柄上调用 CloseHandle() 不会影响同一个互斥锁的其他句柄。

【讨论】:

【参考方案2】:

最严重的后果是线程正在等待互斥锁被解除阻塞。 WaitXxx 调用返回 WAIT_ABANDONED。此时调用 TerminateProcess 将是一个非常好的主意,因为您不知道到底发生了什么。

【讨论】:

WAIT_ABANDONED 仅在线程终止但仍拥有互斥锁时才报告。这与过早在互斥体句柄上调用 CloseHandle() 不同。 @Remy - 我认为您混淆了为 ReleaseMutex() 调用获得的 GetLastError() 值。我说的是 WaitForSingleObject() 和朋友们。 所以你认为 WaitForSingleObject 是个坏主意,在调用 CloseHandle 之前确保线程完成? 呃,不,在线程句柄上使用 WFSO 是找出线程已完成的方法。此评论澄清任何事情的几率必须很低。 是的,我刚刚工作了 12 多个小时……我累了。我明天会发布一个 sn-p 来说明我的意思并确保它没问题,但我想我得到了答案。【参考方案3】:

在这种情况下,CloseHandle() 确实会破坏句柄,但只有在所有句柄都已关闭时,互斥对象才会从内存中删除。 因此,通过 CloseHandle(handle) 您将破坏该句柄,因此 ReleaseMutex(handle) 将不起作用。但是,互斥锁仍将归该线程所有,无法释放,影响其他等待互斥锁的线程。

【讨论】:

以上是关于互斥体上的 CloseHandle,在 ReleaseMutex 之前 - 会发生啥?的主要内容,如果未能解决你的问题,请参考以下文章

21.互斥量

作业对象上的 CloseHandle() 但不终止由 ShellExecute 创建的进程

在同一个互斥锁上的锁定和解锁顺序是不是一致?

window下线程同步之(Mutex(互斥器) )

互斥锁mutex的使用

CloseHandle()函数小记