4.3.4 进程终止运行时出现的情况
当进程终止运行时,下列操作将启动运行:
1) 进程中剩余的所有线程全部终止运行。
2) 进程指定的所有用户对象和G D I对象均被释放,所有内核对象均被关闭(如果没有其他
进程打开它们的句柄,那么这些内核对象将被撤消。但是,如果其他进程打开了它们的句柄,
内核对象将不会撤消)。
3) 进程的退出代码将从S T I L L _ A C T I V E改为传递给E x i t P r o c e s s或Te r m i n a t e P r o c e s s的代码。
4) 进程内核对象的状态变成收到通知的状态(关于传送通知的详细说明,参见第9章)。系
统中的其他线程可以挂起,直到进程终止运行。
5) 进程内核对象的使用计数递减1。
注意,进程的内核对象的寿命至少可以达到进程本身那么长,但是进程内核对象的寿命可
能大大超过它的进程寿命。当进程终止运行时,系统能够自动确定它的内核对象的使用计数。
如果使用计数降为0,那么没有其他进程拥有该对象打开的句柄,当进程被撤消时,对象也被
撤消。
不过,如果系统中的另一个进程拥有正在被撤消的进程的内核对象的打开句柄,那么该进
程内核对象的使用计数不会降为0。当父进程忘记关闭子进程的句柄时,往往就会发生这样的
情况。这是个特性,而不是错误。记住,进程内核对象维护关于进程的统计信息。即使进程已
经终止运行,该信息也是有用的。例如,你可能想要知道进程需要多少C P U时间,或者,你想
通过调用G e t E x i t C o d e P r o c e s s来获得目前已经撤消的进程的退出代码:
该函数查看进程的内核对象(由h P r o c e s s参数来标识),取出内核对象的数据结构中用于标
识进程的退出代码的成员。该退出代码的值在p d w E x i t C o d e参数指向的D W O R D中返回。
可以随时调用该函数。如果调用G e t E x i t C o d e P r o c e s s函数时进程尚未终止运行,那么该函
数就用S T I L L _ A C T I V E标识符(定义为0 x 1 0 3)填入D W O R D。如果进程已经终止运行,便返
回数据的退出代码值。
也许你会认为,你可以编写代码,通过定期调用G e t E x i t C o d e P r o c e s s函数并且检查退出代
码来确定进程是否已经终止运行。大多数情况下,这是可行的,但是效率不高。下一段将介绍
用什么正确的方法来确定进程何时终止运行。
再一次提醒你,应该通过调用C l o s e H a n d l e函数,告诉系统你对进程的统计数据已经不再
感兴趣。如果进程已经终止运行,C l o s e H a n d l e将递减内核对象的使用计数,并将它释放。
This function returns immediately. If the process has not terminted and the function succeeds, the status returned is STILL_ACTIVE. If the process has terminated and the function succeeds, the status returned is one of the following values:
The exit value specified in the ExitProcess or TerminateProcess function.
The return value from the main or WinMain function of the process.
The exception value for an unhandled exception that caused the process to terminate.