互斥体上的 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 之前 - 会发生啥?的主要内容,如果未能解决你的问题,请参考以下文章