Windows 句柄等到所有引用都被释放

Posted

技术标签:

【中文标题】Windows 句柄等到所有引用都被释放【英文标题】:Windows Handle wait until all references are released 【发布时间】:2017-12-14 22:24:02 【问题描述】:

我正在设计的 IPC 系统中有多个进程。每个进程创建一个FileMappingMapViewOfFile 作为自己的内存区域。此外,每个进程创建两个信号量来管理它已经创建的FileMappingMapViewOfFile

为了描述我遇到的问题,假设有 3 个过程:

    ProcessA 创建FileMappingMapViewOfFile 和两个信号量。

    ProcessBProcessCProcessA 类似。

    ProcessA 想向ProcessB 发送一些东西。它连接到FileMappingMapViewOfFile 以及ProcessB 的两个信号量,并发送它想发送的任何内容。

    ProcessB 想要重新打开它的通信。它关闭了它的FileMappingMapViewOfFile 以及它的两个信号量。它向进程AC 发送关闭消息。当进程AC 收到关闭消息时,它们将关闭FileMappingMapViewOfFile 和与ProcessB 关联的两个信号量的句柄。

    ProcessB 已关闭其所有句柄并希望重新打开。当它尝试创建MapViewOfFile 时,它会失败,因为进程AC 尚未关闭ProcessB 的句柄。

现在(作为临时修复),我让ProcessB 在关闭时休眠 100 毫秒,以便进程 A 和 C 有时间关闭它们对 ProcessB 的句柄。但是,我想要一个不涉及睡眠的解决方案。

ProcessB 有没有办法知道对其句柄的所有引用FileMappingMapViewOfFile 和两个信号量)何时被所有其他进程释放? 如果有,我怎么等呢?

【问题讨论】:

所有对它的句柄的引用你在这下面是什么意思? 根据微软的文档,一个对象只有在所有对其句柄的引用都关闭时才会关闭。当您在对象上调用 CloseHandle 时,它只会减少对该对象的引用计数。当引用计数达到0 时,对象将关闭,您可以重新创建它。我想知道是否有办法检查引用计数。 不,你用一般语言描述的内容,你如何尝试实现 ipc - 设计上绝对错误。 “想要重新打开”是问题所在。 that 在实际场景中从来没有用过,进程应该在启动时初始化它的映射,直到它终止才关闭它。同步共享内存访问已经够难了,没有必要让它变得更糟。所以不要这样做,问题解决了。 @RbMm 感谢您对设计的关注。我正在探索新的设计理念并检查性能升级。这就是这个项目的重点,探索。无论如何,设计比描述的要复杂,我需要大约 5 页来详细描述它是如何工作的,而且它实际上非常快速和可靠。 【参考方案1】:

绝对没有 winapi 函数可以做到这一点。您只能尝试打开一个(命名的)对象的句柄,看看它是否因适当的原因而失败。

因此,最简单的解决方法是使用Sleep(0) 或类似的方法在循环中执行您正在尝试的操作。您还可以为此特定目的添加一个额外的同步对象,一个自动重置命名事件,您的ProcessB 可以打开和WaitFor....

【讨论】:

从概念上讲,这非常有用。为了弄清楚这一点,您建议在我关闭句柄后,我尝试重新打开它们直到我成功,当我成功时,这意味着所有其他进程都已释放句柄,因此我是唯一持有它们的人,所以关闭它们再次意味着所有引用都被释放。这是正确的吗? 有点。您也可以反之亦然:调用OpenFileMapping 直到它失败 - 这意味着它的最后一个句柄已关闭。 谢谢。我会尝试一下,希望它会奏效。 我想知道你是否可以回答这个问题。如果我对系统中的每个进程使用namespaces,我可以强制关闭命名空间内的所有句柄吗? 简短回答:否。您不能强制“关闭手柄”。只能通过调用CloseHandle 或在进程退出时关闭句柄。

以上是关于Windows 句柄等到所有引用都被释放的主要内容,如果未能解决你的问题,请参考以下文章

资源类型

windoes任务管理器中的“句柄数”是啥意思!

C# 中的内存泄漏

智能指针循环引用——你真的懂了吗?

智能指针循环引用——你真的懂了吗?

如何释放Python占用的内存