Windows 句柄等到所有引用都被释放
Posted
技术标签:
【中文标题】Windows 句柄等到所有引用都被释放【英文标题】:Windows Handle wait until all references are released 【发布时间】:2017-12-14 22:24:02 【问题描述】:我正在设计的 IPC 系统中有多个进程。每个进程创建一个FileMapping
和MapViewOfFile
作为自己的内存区域。此外,每个进程创建两个信号量来管理它已经创建的FileMapping
和MapViewOfFile
。
为了描述我遇到的问题,假设有 3 个过程:
ProcessA
创建FileMapping
、MapViewOfFile
和两个信号量。
ProcessB
和 ProcessC
与 ProcessA
类似。
ProcessA
想向ProcessB
发送一些东西。它连接到FileMapping
和MapViewOfFile
以及ProcessB
的两个信号量,并发送它想发送的任何内容。
ProcessB
想要重新打开它的通信。它关闭了它的FileMapping
和MapViewOfFile
以及它的两个信号量。它向进程A
和C
发送关闭消息。当进程A
和C
收到关闭消息时,它们将关闭FileMapping
、MapViewOfFile
和与ProcessB
关联的两个信号量的句柄。
ProcessB
已关闭其所有句柄并希望重新打开。当它尝试创建MapViewOfFile
时,它会失败,因为进程A
和C
尚未关闭ProcessB
的句柄。
现在(作为临时修复),我让ProcessB
在关闭时休眠 100 毫秒,以便进程 A 和 C 有时间关闭它们对 ProcessB
的句柄。但是,我想要一个不涉及睡眠的解决方案。
ProcessB
有没有办法知道对其句柄的所有引用(FileMapping
、MapViewOfFile
和两个信号量)何时被所有其他进程释放? 如果有,我怎么等呢?
【问题讨论】:
所有对它的句柄的引用你在这下面是什么意思? 根据微软的文档,一个对象只有在所有对其句柄的引用都关闭时才会关闭。当您在对象上调用CloseHandle
时,它只会减少对该对象的引用计数。当引用计数达到0
时,对象将关闭,您可以重新创建它。我想知道是否有办法检查引用计数。
不,你用一般语言描述的内容,你如何尝试实现 ipc - 设计上绝对错误。
“想要重新打开”是问题所在。 that 在实际场景中从来没有用过,进程应该在启动时初始化它的映射,直到它终止才关闭它。同步共享内存访问已经够难了,没有必要让它变得更糟。所以不要这样做,问题解决了。
@RbMm 感谢您对设计的关注。我正在探索新的设计理念并检查性能升级。这就是这个项目的重点,探索。无论如何,设计比描述的要复杂,我需要大约 5 页来详细描述它是如何工作的,而且它实际上非常快速和可靠。
【参考方案1】:
绝对没有 winapi 函数可以做到这一点。您只能尝试打开一个(命名的)对象的句柄,看看它是否因适当的原因而失败。
因此,最简单的解决方法是使用Sleep(0)
或类似的方法在循环中执行您正在尝试的操作。您还可以为此特定目的添加一个额外的同步对象,一个自动重置命名事件,您的ProcessB
可以打开和WaitFor....
。
【讨论】:
从概念上讲,这非常有用。为了弄清楚这一点,您建议在我关闭句柄后,我尝试重新打开它们直到我成功,当我成功时,这意味着所有其他进程都已释放句柄,因此我是唯一持有它们的人,所以关闭它们再次意味着所有引用都被释放。这是正确的吗? 有点。您也可以反之亦然:调用OpenFileMapping
直到它失败 - 这意味着它的最后一个句柄已关闭。
谢谢。我会尝试一下,希望它会奏效。
我想知道你是否可以回答这个问题。如果我对系统中的每个进程使用namespaces
,我可以强制关闭命名空间内的所有句柄吗?
简短回答:否。您不能强制“关闭手柄”。只能通过调用CloseHandle
或在进程退出时关闭句柄。以上是关于Windows 句柄等到所有引用都被释放的主要内容,如果未能解决你的问题,请参考以下文章