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