在Closehandle()中关闭句柄后,进程无法终止。
我有一个由Createprocess()api创建的进程。即使在关闭其手柄后,它仍在运行。
从msdn,他们说closehandle关闭句柄并且没有终止进程。必须为此调用终止线程。那为什么Closehandle()?
但是当我检查了关闭句柄的返回值时,它成功了。如果是这样,我想知道在这个closehandle()中实际完成了什么,以及为什么它成功返回。我想知道使用它的句柄可以在进程上完成所有操作。我感到误导,因为closehandle()成功但过程仍在继续!
进程句柄中实际包含的内容也很好,与其他类型的句柄有什么不同吗?(文件,I / O等)
答案 0 :(得分:7)
TerminateProcess
。关闭句柄并不会终止该过程,因为这会很荒谬。流程通常彼此独立地运行。如果关闭进程句柄终止了相应的进程,则不会出现这种情况,因为当程序退出时,它所持有的所有打开句柄都将被关闭。例如,这意味着如果资源管理器崩溃,您启动的每个程序将立即终止。这将是一个灾难,因此关闭进程句柄的设计不会终止程序。
终止进程几乎总是一个非常糟糕的主意。终止线程也是如此。如果你能避免它,就不要这样做。如果您希望线程/进程退出,请向其发送消息并等待退出(代表其自身)。这可以保证数据得到正确保存并保持一致状态,不会泄漏资源,也不会发生严重冲突(例如线程在锁定时终止)。 终止线程通常很麻烦,有时甚至是灾难性的。终止过程也是如此。当进程或线程陷入无限循环并且没有响应时,它只是“允许”终止进程或线程。
您可以使用句柄执行某些操作,其中包括ReadProcessMemory
,WriteProcessMemory
,CancelIoEx
,运行调试程序,使用PSAPI以及其他一些操作。您也可以等待手柄,它会在进程退出时发出信号。这是一种非常简单的进程间同步方式
另一方面,只要您将句柄保持打开状态,操作系统就无法释放资源,从而拥有访问这些资源的“合法权利”。例如,如果流程(或至少其结构)根本不存在,您如何等待流程?
这个(以及句柄本身是一个资源的事实)是你应该尽快关闭句柄的原因如果你不需要它。无限期地持有它需要操作系统保持不需要但不能被释放的资源 关闭句柄会告诉操作系统您不再需要它,因此每当操作系统想要释放与该过程相关的所有资源时,它都可以这样做。
与所有句柄一样,进程句柄只是一个不包含任何内容的不透明整数。它是内核拥有的表中的索引,技术上是void*
,但这只是一个实现细节。它引用的实际内核结构不是你可以直接访问的东西,不管怎么说都不是一种简单的方法。
答案 1 :(得分:4)
句柄是对某些内核管理的引用计数对象的引用。通常,关闭对象的最后一个句柄将导致此类对象的销毁。
但是 :当关闭最后一个句柄时,进程和线程没有被杀死,你可以认为他们已经开始独立生活了#34;在开始之后。没有这个例外,你不可能有一个比其父母更长的过程,因为每个过程都是如此。句柄在进程终止时自动关闭(并且线程比其父级需要不必要的并发症)。
无论如何,所有这些都记录在案:如果您阅读documentation of CloseHandle,您会发现:
关闭线程句柄不会终止关联的线程或 删除线程对象。关闭进程句柄不会终止 关联的进程或删除进程对象。删除一个 线程对象,必须终止线程,然后关闭所有句柄 到线程。有关更多信息,请参阅终止线程。至 删除进程对象,必须终止进程,然后关闭 进程的所有句柄。有关更多信息,请参阅终止a 过程
答案 2 :(得分:2)
您所描述的是设计行为。一个进程独立运行,可能会打开零个或多个句柄,让其持有者以某种方式控制进程。握住手柄后,您有责任关闭它。
终止流程是另一回事,基本上你不应该在外部终止:你永远不知道你在哪里停止流程。您应该以某种方式表示您希望进程终止,以便进程可以在内部并优雅地终结并终止其活动。