Closehandle()不会终止进程

时间:2014-04-03 10:22:25

标签: windows winapi process msdn

在Closehandle()中关闭句柄后,进程无法终止。

我有一个由Createprocess()api创建的进程。即使在关闭其手柄后,它仍在运行。

从msdn,他们说closehandle关闭句柄并且没有终止进程。必须为此调用终止线程。那为什么Closehandle()?

但是当我检查了关闭句柄的返回值时,它成功了。如果是这样,我想知道在这个closehandle()中实际完成了什么,以及为什么它成功返回。我想知道使用它的句柄可以在进程上完成所有操作。我感到误导,因为closehandle()成功但过程仍在继续!

进程句柄中实际包含的内容也很好,与其他类型的句柄有什么不同吗?(文件,I / O等)

3 个答案:

答案 0 :(得分:7)

为什么关闭句柄不会终止进程?必须为此致电TerminateProcess

关闭句柄并不会终止该过程,因为这会很荒谬。流程通常彼此独立地运行。如果关闭进程句柄终止了相应的进程,则不会出现这种情况,因为当程序退出时,它所持有的所有打开句柄都将被关闭。例如,这意味着如果资源管理器崩溃,您启动的每个程序将立即终止。这将是一个灾难,因此关闭进程句柄的设计不会终止程序。

终止进程几乎总是一个非常糟糕的主意。终止线程也是如此。如果你能避免它,就不要这样做。如果您希望线程/进程退出,请向其发送消息并等待退出(代表其自身)。这可以保证数据得到正确保存并保持一致状态,不会泄漏资源,也不会发生严重冲突(例如线程在锁定时终止)。 终止线程通常很麻烦,有时甚至是灾难性的。终止过程也是如此。当进程或线程陷入无限循环并且没有响应时,它只是“允许”终止进程或线程。

那么你为什么还要关闭手柄?如果你必须关闭手柄,为什么还要拿一个呢?

您可以使用句柄执行某些操作,其中包括ReadProcessMemoryWriteProcessMemoryCancelIoEx,运行调试程序,使用PSAPI以及其他一些操作。您也可以等待手柄,它会在进程退出时发出信号。这是一种非常简单的进程间同步方式 另一方面,只要您将句柄保持打开状态,操作系统就无法释放资源,从而拥有访问这些资源的“合法权利”。例如,如果流程(或至少其结构)根本不存在,您如何等待流程?

这个(以及句柄本身是一个资源的事实)是你应该尽快关闭句柄的原因如果你不需要它。无限期地持有它需要操作系统保持不需要但不能被释放的资源 关闭句柄会告诉操作系统您不再需要它,因此每当操作系统想要释放与该过程相关的所有资源时,它都可以这样做。

流程句柄中包含哪些内容?

与所有句柄一样,进程句柄只是一个不包含任何内容的不透明整数。它是内核拥有的表中的索引,技术上是void*,但这只是一个实现细节。它引用的实际内核结构不是你可以直接访问的东西,不管怎么说都不是一种简单的方法。

答案 1 :(得分:4)

句柄是对某些内核管理的引用计数对象的引用。通常,关闭对象的最后一个句柄将导致此类对象的销毁。

但是 :当关闭最后一个句柄时,进程和线程没有被杀死,你可以认为他们已经开始独立生活了#34;在开始之后。没有这个例外,你不可能有一个比其父母更长的过程,因为每个过程都是如此。句柄在进程终止时自动关闭(并且线程比其父级需要不必要的并发症)。

无论如何,所有这些都记录在案:如果您阅读documentation of CloseHandle,您会发现:

  

关闭线程句柄不会终止关联的线程或   删除线程对象。关闭进程句柄不会终止   关联的进程或删除进程对象。删除一个   线程对象,必须终止线程,然后关闭所有句柄   到线程。有关更多信息,请参阅终止线程。至   删除进程对象,必须终止进程,然后关闭   进程的所有句柄。有关更多信息,请参阅终止a   过程

答案 2 :(得分:2)

您所描述的是设计行为。一个进程独立运行,可能会打开零个或多个句柄,让其持有者以某种方式控制进程。握住手柄后,您有责任关闭它。

终止流程是另一回事,基本上你不应该在外部终止:你永远不知道你在哪里停止流程。您应该以某种方式表示您希望进程终止,以便进程可以在内部并优雅地终结并终止其活动。