当函数C r e a t eP r o c e s s的参数b I n h e r i t H a n d l e传递为T R U E时,那么子进程就可以继承父进程的可继承句柄值。操作系统创建该新子进程后,但是不允许子进程立即开始执行它的代码。当然,系统为子进程创建一个新的和空的句柄表,就像它为任何新进程创建句柄表那样。不过,由于将T R U E传递给了C r e a t e P r o c e s s的b I n h e r i t H a n d l e s参数,因此系统要进行另一项操作,即它要遍历父进程的句柄表,对于它找到的包含有效的可继承句柄的每个项目,系统会将该项目准确地拷贝到子进程的句柄表中。该项目拷贝到子进程的句柄表中的位置将与父进程的句柄表中的位置完全相同。这个情况非常重要,因为它意味着在父进程与子进程中,标识内核对象所用的句柄值是相同的。
除了拷贝句柄表项目外,系统还要递增内核对象的使用计数,因为现在两个进程都使用该对象。如果要撤消内核对象,那么父进程和子进程必须调用该对象上的C l o s e H a n d l e函数,也可以终止进程的运行。子进程不必首先终止运行,但是父进程也不必首先终止运行。实际上,C r e a t e P r o c e s s函数返回后,父进程可以立即关闭对象的句柄,而不影响子进程对该对象进行操作的能力。
需要注意的是,对象句柄的继承性只有在生成子进程的时候才能使用。如果父进程准备创建带有可继承句柄的新内核对象,那么已经在运行的子进程将无法继承这些新句柄。
另一个方法是让父进程将一个环境变量添加给它的环境程序块。该变量的名字是子进程知道要查找的某种信息,而变量的值则是内核对象要继承的值。这样,当父进程生成子进程时,子进程就继承父进程的环境变量,并且能够非常容易地调用G e t E n v i r o n m e n t Va r i a b l e函数,以获取被继承对象的句柄值。如果子进程要生成另一个子进程,那么使用这种方法是极好的,因为环境变量可以被再次继承。
大多数情况下,应用程序将另一个进程作为独立的进程来启动。这意味着进程创建和开始运行后,父进程并不需要与新进程进行通信,也不需要在完成它的工作后父进程才能继续运行。这就是E x p l o r e r的运行方式。当E x p l o r e r为用户创建一个新进程后,它并不关心该进程是否继续运行,也不在乎用户是否终止它的运行。若要放弃与子进程的所有联系, E x p l o r e r必须通过调用C l o s e H a n d l e来关闭它与新进程及它的主线程之间的句柄。下面的代码示例显示了如何创建新进程以及如何让它以独立方式来运行:
PROCESS_INFOMATION pi;
//Spawn the child process
BOOL fSuccess = CreateProcess(..., &pi);
if (fSuccess)
{
// Allow the system to destroy the process & thread kernel
// objects as soon as the child process terminates.
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}