首页 文章

Closehandle()不会终止进程

提问于
浏览
2

在Closehandle()中关闭其句柄后,该过程无法终止 .

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

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

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

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

3 回答

  • 4

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

    But :关闭最后一个句柄时没有杀死进程和线程,你可以认为它们在启动后"start living on their own" . 如果没有这个例外,你就无法在进程终止时自动关闭句柄(并且线程比其父级需要不必要的并发症) .

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

    关闭线程句柄不会终止关联的线程或删除线程对象 . 关闭进程句柄不会终止关联的进程或删除进程对象 . 要删除线程对象,必须终止线程,然后关闭线程的所有句柄 . 有关更多信息,请参阅终止线程 . 要删除进程对象,必须终止进程,然后关闭进程的所有句柄 . 有关更多信息,请参阅终止进程 .

  • 7

    为什么关闭句柄不会终止进程?必须为此调用TerminateProcess .

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

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

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

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

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

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

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

  • 2

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

    终止过程是另一回事,你基本上没有预料到从外部终止:你永远不知道你在哪里停止这个过程 . 您需要以某种方式表示您希望进程终止,以便进程可以在内部并优雅地终结并终止其活动 .

相关问题