TerminateProcess(GetCurrentProcess(),exit_code)之后是否需要等待?

TerminateProcess的文档部分说:

This function stops execution of all threads within the process and requests cancellation of all pending I/O. ... TerminateProcess is asynchronous; it initiates termination and returns immediately. If you need to be sure the process has terminated, call the WaitForSingleObject function with a handle to the process. 

这对于如果使用TerminateProcess进行自杀过程会发生什么情况会有些模棱两可,如下所示:

 TerminateProcess(GetCurrentProcess(), exit_code) 

从逻辑上讲,这应该是足够的,但文档 ,执行可能会继续之后,这是很危险的,如果你正在调用TerminateProcess由于一个错误,使您的进程处于不确定的状态。

我发现的最接近的东西是确认自杀等待不需要的是_invoke_watson的源代码:

 C:\Program Files (x86)\Windows Kits\10\Source\10.0.10240.0\ucrt\misc\invalid_parameter.cpp 

这个函数做的最后一件事就是自己调用TerminateProcess – 不用等待。

这是很好的确定,我想在这里问这个答案可以作为文件的补充。

我从离线的人那里得到了这个答案,他们宁愿不要把它贴在这里:

我对用户模式文档的看法是,TerminateProcess通常是一个进程对另一个进程所做的事情,文档是为了这个通用性而编写的,在这个意义上是正确和合理的。

给TerminateProcess一个其他进程的句柄,你当然希望这个调用回到你的继续操作。

这个文档的重点是,调用的成功并不意味着其他进程已经终止,只是终止已经成功。

如果你不仅仅依靠这个,那么你肯定会做错事。 调查究竟什么是可靠的,甚至是思考的,因此对我来说似乎没有什么用处。 尽管我已经困扰了,但我已经意识到当TerminateProcess返回给你时,其他进程及其所有线程已经被标记为已终止 – 从字面上看,它们已经在ETHREAD中设置了终止位 – 但继续执行APC,通常用于完成或取消I / O等事情。 虽然这种持续执行受到很大限制,但可能需要一些无限期的时间。 所以,如果你需要知道所有的执行都已经完成了,那么你需要注意这个过程得到信号。

当然,调用TerminateProcess来终止另一个进程是一件残酷的事情,文档中也有一个说法。

相同的过程

调用TerminateProcess来终止你自己的进程并不是那么残酷。 除了一个例外,这是非常不得已的,即使在这种情况下,也是非常绝望的一个。 任何执行此操作的人都必须拥有比调用可能返回的更多的问题,否则肯定会调用显式不返回的ExitProcess(但可能会使进程处于死锁状态)。

通过TerminateProcess自行终止会引入一个被终止的线程是当前线程的情况。 终止APC处理不会被激活:在Windows 7内核中,请参阅PspTerminateThreadByPointer,它再次使得当前线程的用户模式终止进入不返回PspExitThread的特殊情况,而不是将APC排队最终退出。

所以,我的阅读是TerminateProcess的-1作为句柄没有返回,但是如果你在内核中执行最后一个调用线程的指令,你可以看到你的进程中的其他线程仍然可以执行过程APC,但你的APC队列已经耗尽,即将被切换,永远不会回来。 事实上,如果在这个时候你的线程以某种方式有一个APC来处理,那么内核就会检查错误!

顺便说一句,TerminateProcess的例外是残酷的,它实质上是NTDLL甚至通过ExitProcess相对温和的自我终止做的最后一件事情。 它肯定是众所周知的,但总是让我感到惊讶的是,要处理RtlExitUserProcess,NTDLL将两次调用NtTerminateProcess。 首先,有用户模式清理和对NtTerminateProcess的处理为NULL的调用。 如果成功,则有更多的用户模式清除,以NtTerminateProcess调用结束,给出-1作为句柄。

那最后一个调用就是你从TerminateProcess中得到的-1作为句柄。 当你通过TerminateProcess自行终止时,你只是跳过了清理过程,在用户模式和内核模式下,你都可以从ExitProcess中获得。 无论如何,当TerminateProcess实际上是由NTDLL作为ExitProcess的结束时,显然不会返回。