一个僵尸进程产生的过程是:父进程调用fork创建子进程后,子进程运行至其终止。进程终止后有些信息对于父进程和内核还是很有用的,例如进程的ID号、进程的退出状态、进程运行的CPU时间等。因此进程运行终止后,系统会回收所有内核分配给它的内存、关闭它所打开的文件等,但是还会保留以上极少的信息,以供父进程使用,系统会向父进程发送SIGCHLD信号,父进程应及时调用wait函数来为子进程收尸,做一些收尾工作。但如果父进程没有及时调用wait函数,则子进程的进程状态变成ZOMBIE,即僵尸进程僵尸进程会一起占用内存且无法通过使用kill杀死清除,除非父进程随后调用wait函数或父进程也运行结束或其它因素父进程被杀终结等,僵尸进程才会被回收。

  以前一篇文章【C/C++】多进程:父进程监听子进程状态 wait()的使用的示例代码加以简单修改下,用来演示僵尸进程:

    // if (count > CHILD_COUNT) {
    // 原CHILD_COUNT改为10
    if (count > 10) {


FILE * fMain = freopen("/Users/sodino/workspace/xcode/Define/Define/main.txt", "w", stdout);
// 在重定向父进程的标准输出流后,添加上如下的延时代码
int count = 0;
while(1) {
    printTime();
    printf("Main Process sleep10, count=%d \n", count);
    sleep(10);
    if (count > 100) {
        break;
    }
}

  编译后,运行,效果如下图:
zombie.

  首先在子进程运行期间直接查看进程状态,可以看到两个a.out进程。

  子进程打印完10行日志后,再查看进程状态,可以看到子进程已经进程zombie状态,即僵尸进程

  用命令kill掉父进程,或等待父进程执行到wait函数,则可发现子进程已经被系统回收了。

  文章开头提到系统会向父进程发送SIGCHLD信号,那下一篇就来讲讲如何注册信号监听及处理函数:多进程:信号量的监听与处理函数