在linux中子进程是由父进程创建的。如果进程出现异常就出现一些问题,僵尸进程和孤儿进程。
孤儿进程:一个父进程退出,而他的子进程还在运行,那么子进程将会成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养。
僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。
下面用例子来了解孤儿进程和僵尸进程
1. 孤儿进程
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
int main()
{
pid_t pid;
//创建一个进程
pid = fork();
//创建失败
if (pid < 0)
{
perror("fork error:");
exit(1);
}
//子进程
if (pid == 0)
{
printf("I am the child process.\n");
//输出进程ID和父进程ID
printf("pid: %d\tppid:%d\n",getpid(),getppid());
printf("I will sleep five seconds.\n");
//睡眠5s,保证父进程先退出
sleep(5);
printf("pid: %d\tppid:%d\n",getpid(),getppid());
printf("child process is exited.\n");
}
//父进程
else
{
printf("I am father process.\n");
//父进程睡眠1s,保证子进程输出进程id
sleep(1);
printf("father process is exited.\n");
}
return 0;
}
从运行结果可以看出,开始父进程号为:8965 子进程号为:8966
在父进程结束,子进程继续运行时,父进程号为:1 子进程号为:8966
现在子进程已经是孤儿进程,子进程也已经被init进程(进程号为1)所收养。
2.僵尸进程
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
pid_t pid;
pid = fork();
if(pid < 0)
printf("error occurred!\n");
else if(pid == 0) {
printf("Hi father!\n");
exit(0); //子进程退出
}
else {
sleep(10); //父进程睡眠10秒,子进程已经退出,父进程并没有调用wait或waitpid获取子进程的状态信息
wait(NULL);
}
}
由图可见,子进程的状态变为Z,僵尸状态