查询内核以获得其父进程的 PID,或者其任何子进程的执行状态。例如,进程可以创建一个子进程来执行特定的任务,然后调用诸如 wait() 这样的一些库函数检查子进程是否终止。如果子进程已经终止,那么,它的终止代号将告诉父进程这个任务是否已成功地完成。调用之后,才允许这样做。这就是引入僵死状态的原因:尽管从技术上来说进程已死,但必须保存它的描述符,直到父进程得到通知。如果一个进程已经终止,但是它的父进程尚未调用 wait() 或 waitpid() 对它进行清理,这时的进程状态称为僵死状态,处于僵死状态的进程称为僵尸进程(zombie process)。任何进程在刚终止时都是僵尸进程,正常情况下,僵尸进程都立刻被父进程清理了。
的
调用 wait 清理子进程:
<span style="color: #0000ff">int
{
<span style="color: #0000ff">int i = <span style="color: #800080">100<span style="color: #000000">;
pid_t pid=<span style="color: #000000">fork();
<span style="color: #0000ff">if(pid < <span style="color: #800080">0<span style="color: #000000">)
{
perror(<span style="color: #800000">"<span style="color: #800000">fork Failed.<span style="color: #800000">"<span style="color: #000000">);
exit(<span style="color: #800080">1<span style="color: #000000">);
}
<span style="color: #0000ff">if(pid > <span style="color: #800080">0<span style="color: #000000">)
{
printf(<span style="color: #800000">"<span style="color: #800000">This is the parent process. My PID is %d.\n<span style="color: #800000">"<span style="color: #000000">,getpid());
<span style="color: #0000ff">for(; i > <span style="color: #800080">0; i--<span style="color: #000000">)
{
sleep(<span style="color: #800080">1<span style="color: #000000">);
}
}
<span style="color: #0000ff">else <span style="color: #0000ff">if(pid == <span style="color: #800080">0<span style="color: #000000">)
{
printf(<span style="color: #800000">"<span style="color: #800000">This is the child process. My PID is: %d. My PPID is: %d.\n<span style="color: #800000">"<span style="color: #000000">,getpid(),getppid());
}
<span style="color: #0000ff">return <span style="color: #800080">0<span style="color: #000000">;
}
代码保存到文件 zomprocdemo.c 文件中,并执行下面的命令编译:
退出,但是父进程没有退出也没有通过 wait() 调用处理子进程。我们使用 ps 命令查看进程的状态:
退出。当父进程退出后,子进程会变成孤儿进程,此时它会被一个管理进程收养。在不同的系统中,这个管理进程不太一样,早期一般是 init 进程,Ubuntu 上是 upstart,还有近来的 Systemd。但是它们都完成相同的任务,就是 wiat() 这些孤儿进程,并最终释放它们占用的系统进程表中的资源。这样,这些已经僵死的孤儿进程就彻底的被清除了。
退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等。但是仍然为其保留一定的信息(包括进程号 PID,退出状态 the termination status of the process,运行时间 the amount of cpu time taken by the process 等)。直到父进程通过 wait / waitpid 来取时才释放。
调用 wait / waitpid 的话, 那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程。
<span style="color: #0000ff">int
{
pid_t pid;
pid
{
perror(<span style="color: #800000">"<span style="color: #800000">fork Failed<span style="color: #800000">"<span style="color: #000000">);
exit(<span style="color: #800080">1<span style="color: #000000">);
}
<span style="color: #0000ff">if (pid == <span style="color: #800080">0<span style="color: #000000">) {
<span style="color: #0000ff">int<span style="color: #000000"> i;
<span style="color: #0000ff">for (i = <span style="color: #800080">3; i > <span style="color: #800080">0; i--<span style="color: #000000">)
{
printf(<span style="color: #800000">"<span style="color: #800000">This is the child\n<span style="color: #800000">"<span style="color: #000000">);
sleep(<span style="color: #800080">1<span style="color: #000000">);
}
<span style="color: #008000">//<span style="color: #008000"> exit with code 3 for test.
exit(<span style="color: #800080">3<span style="color: #000000">);
}
<span style="color: #0000ff">else<span style="color: #000000">
{
<span style="color: #0000ff">int<span style="color: #000000"> stat_val;
wait(&<span style="color: #000000">stat_val);
<span style="color: #0000ff">if<span style="color: #000000"> (WIFEXITED(stat_val))
{
printf(<span style="color: #800000">"<span style="color: #800000">Child exited with code %d\n<span style="color: #800000">"<span style="color: #000000">,WEXITSTATUS(stat_val));
}
}
<span style="color: #0000ff">return <span style="color: #800080">0<span style="color: #000000">;
}
原文链接:/systemd/71427.html