关于Windows:Closehandle()不会终止进程

Closehandle() not terminating the process

在Closehandle()中关闭其句柄后,该过程不会终止。

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

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

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

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


为什么关闭手柄不会终止该过程?为此必须调用TerminateProcess

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

终止进程几乎总是一个坏主意。终止线程也是如此。如果可以避免,切勿这样做。如果要退出线程/进程,请向其发送一条消息,然后等待其退出(以自己的名义)。这保证了数据已正确保存并且处于一致状态,不会泄漏资源,并且不会发生严重冲突(例如,线程在持有锁的同时被终止)。
终止线程通常很麻烦,有时甚至是灾难性的。终止过程也是如此。当进程或线程陷入无限循环且无响应时,才"允许"终止该进程或线程。

那么,为什么无论如何都必须关闭手柄,如果必须关闭手柄,为什么又要拿一个呢?

您可以使用句柄执行某些操作,例如,ReadProcessMemoryWriteProcessMemoryCancelIoEx,运行调试器,使用PSAPI等。您也可以等待句柄,当进程退出时会发出信号。这是进程间同步的非常简单的方法。
另一方面,只要您打开句柄并因此拥有访问这些资源的"合法权利",操作系统就无法释放资源。例如,如果该进程(或至少它的结构)根本不存在,您如何等待该进程?

这就是句柄本身就是一种资源的事实,这就是为什么您不需要时应尽快关闭该句柄的原因。无限期持有它需要操作系统保留不需要但无法释放的资源。
关闭句柄会告诉操作系统您不再需要它,因此只要OS想要释放与该进程关联的所有资源,它都可以这样做。

流程句柄中包含什么?

像所有句柄一样,进程句柄只是不包含任何内容的不透明整数。它是内核拥有的表中的索引,从技术上讲,它是void*,但这仅是实现细节。它所指的实际内核结构不是您可以直接访问的,无论如何都不容易。


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

但是:进程和线程在关闭最后一个句柄时不会被杀死,您可以认为它们在启动后"开始独立运行"。没有这个例外,您将无法使进程的父进程失效,因为每个进程的句柄在进程终止时会自动关闭(并且使线程的父进程失效会导致不必要的复杂性)。

无论如何,所有这些都已记录在案:如果您阅读CloseHandle的文档,将会发现:

Closing a thread handle does not terminate the associated thread or
remove the thread object. Closing a process handle does not terminate
the associated process or remove the process object. To remove a
thread object, you must terminate the thread, then close all handles
to the thread. For more information, see Terminating a Thread. To
remove a process object, you must terminate the process, then close
all handles to the process. For more information, see Terminating a
Process.


您描述的是设计使然。一个进程自己运行,它可能打开了零个或多个句柄,这使它们的持有者可以通过某些方式控制该进程。握住手柄后,您有责任关闭它。

终止过程是另一回事,基本上不希望您从外部终止:您永远不知道确切地在何处停止了该过程。您应该以某种方式发出信号,表明您想要终止该进程,以便该进程可以弄清楚它并在内部和优美地终止其活动。