Winapi “安全吗?”;“双重关闭”;使用CloseHandle的句柄?

Winapi “安全吗?”;“双重关闭”;使用CloseHandle的句柄?,winapi,handles,Winapi,Handles,多次调用CloseHandle有什么意义 文档说“你不应该”,但我认为我有一个实际的例子,在命名管道中,句柄可能会在外部关闭(见文章末尾) 在本例中,CloseHandle在调试模式下抛出一个异常,这向我表明开发人员认为这是严重的,但文档并不完全清楚 (礼貌的要求:请避免回答“不要!”:-)。当然,一个人应该避免不止一次地关闭一个把手,当然也有很好的技巧来帮助你:我只是对如果你不关闭把手会发生什么感兴趣) 我听一些人建议,如果这个句柄被操作系统很快重用,你可能会关闭另一个不同的句柄 这可能吗 W

多次调用CloseHandle有什么意义

文档说“你不应该”,但我认为我有一个实际的例子,在命名管道中,句柄可能会在外部关闭(见文章末尾)

在本例中,CloseHandle在调试模式下抛出一个异常,这向我表明开发人员认为这是严重的,但文档并不完全清楚

(礼貌的要求:请避免回答“不要!”:-)。当然,一个人应该避免不止一次地关闭一个把手,当然也有很好的技巧来帮助你:我只是对如果你不关闭把手会发生什么感兴趣)

我听一些人建议,如果这个句柄被操作系统很快重用,你可能会关闭另一个不同的句柄

这可能吗

Windows如何选择句柄ID

是否可以保证句柄值的重用频率

(例如,TCP确保端口号在特定时间段内不能重复使用)

你能按不同的手柄类型关闭手柄吗?例如,我是否会认为我正在关闭一个管道,但最终却关闭了一个活动

谢谢

约翰


(上下文:我在客户机/服务器模型中使用命名管道。在我看来,很难确保只有一方保证关闭句柄,例如在进程崩溃/终止的情况下。也许我错了,但在我看来,MSDN示例代码确实允许客户机关闭共享句柄,然后在服务器尝试时关闭要关闭它,它已经关闭。

简单到可以检查:

HANDLE h = 0;
h = CreateMutex(NULL, TRUE, NULL);
printf("%X\n", h);
CloseHandle(h);
h = 0;
h = CreateMutex(NULL, TRUE, NULL);
printf("%X\n", h);
在我的WinXP x64中,这产生了:

2E8
2E8
这就是你想要的。
与TCP端口不同,句柄会立即回收


使用您最喜欢的API或其任何组合重复此实验。

您可能对管道有错误的想象。它有两个端点,每个端点由不同的句柄表示。是的,必须调用CloseHandle两次才能使管道实例消失。但由于它们是不同的句柄,因此永远不会导致任何问题。还要注意at handle实例是特定于进程的。即使它们在两个进程中具有相同的值,它们也不会引用相同的管道端点。

可能会发生两种情况:

  • 关闭由其他代码打开的句柄。这可能不会影响您的代码,但对其他代码来说可能是灾难性的
  • 如果运行时附加了调试器,则会使应用程序崩溃,因为操作系统在检测到关闭无效句柄时会引发异常

  • 这两种方法都不是特别吸引人的,IMHO。

    +1,句柄也可以用于任何类型的对象-可能是互斥对象,也可能是其他对象。执行CloseHandle()两次可能会产生令人惊讶的结果。您指的是什么“共享句柄”?每个进程都应该创建并关闭自己的句柄(相同)管道。句柄是如何被共享的?唉,答案是“不要”,但那是因为句柄根本不应该被共享。嗯,也许我误解了。但我肯定看到过这样的问题:管道的客户端关闭管道,然后服务器抛出“无效句柄”异常(在调试模式下)。