【问题标题】:Closehandle() not terminating the processClosehandle() 没有终止进程
【发布时间】:2014-05-15 02:35:01
【问题描述】:

CloseHandle() 中关闭其句柄后,该进程并未终止。

我有一个由CreateProcess() api 创建的进程。即使关闭了它的句柄,它仍然在运行。

来自 msdn,他们说 CloseHandle() 关闭句柄并且不终止进程。必须为此调用终止线程。那为什么CloseHandle()

但是当我检查CloseHandle()的返回值时,它成功了。如果是这样,我想知道这个CloseHandle() 中实际做了什么以及为什么它成功返回。我想知道使用它的句柄可以对进程进行哪些操作。我觉得有误导性,CloseHandle() 成功了,但进程仍在继续!

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

【问题讨论】:

  • 以此类推,关闭文件句柄并不会删除文件。

标签: windows winapi process msdn


【解决方案1】:

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

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

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

那你为什么要关闭手柄,如果你必须关闭它,你为什么要得到一个呢?

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

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

进程句柄中包含什么?

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

【讨论】:

    【解决方案2】:

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

    但是:进程和线程在关闭最后一个句柄时并没有被杀死,你可以认为它们在启动后“开始自生自灭”。如果没有这个例外,你不可能让一个进程比它的父进程活得更久,因为每个进程的句柄都会在进程终止时自动关闭(并且让一个线程比它的父进程活得更久会带来不必要的复杂性)。

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

    关闭线程句柄不会终止关联的线程或 删除线程对象。关闭进程句柄不会终止 关联的进程或删除进程对象。删除一个 线程对象,必须终止线程,然后关闭所有句柄 到线程。有关详细信息,请参阅终止线程。到 删除进程对象,必须终止进程,然后关闭 进程的所有句柄。有关详细信息,请参阅终止 处理。

    【讨论】:

      【解决方案3】:

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

      进程的终止是另一回事,您基本上不应该在外部终止:您永远不知道您在哪里停止了该进程。您应该以某种方式发出您希望进程终止的信号,以便该进程可以找出它并在内部优雅地终止其活动。

      【讨论】:

        猜你喜欢
        • 2018-03-11
        • 1970-01-01
        • 1970-01-01
        • 2021-07-26
        • 2010-09-29
        • 2011-01-21
        • 2010-10-14
        • 1970-01-01
        • 2022-06-17
        相关资源
        最近更新 更多