第7章 进程关系(1)_守护、孤儿和僵尸进程
1. 守护、孤儿和僵尸进程
(1)守护进程
①守护进程(daemon)是生存期长的一种进程。它们常常在系统引导装入时启动,在系统关闭时终止。
②所有守护进程都以超级用户(用户ID为0)的优先权运行。
③守护进程没有控制终端
④守护进程的父进程都是init进程(1号进程)。
(2)孤儿进程:父进程先结束,子进程就成为孤儿进程,会由1号进程(init进程)领养。
【编程实验】产生孤儿进程
//process_orphen.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
//孤儿进程。演示时启动另一个终端登录来查看子进程的状态
//由于父进程先结束,子进程会由init进程领养。
int main(void)
{
pid_t pid = fork();
if(pid < 0){
perror("fork error");
exit(1);
}else if(pid > 0){ //parent process
printf("%d deaded\n", getpid());
exit(0); //父进程终止
}else{
sleep(4); //让父进程先终止,子进程变成孤儿进程,会由1号进程领养
printf("pid: %d, ppid: %d\n", getpid(), getppid());//ppid=1
}
return 0;
}
(3)僵尸进程
①如果子进程先结束,父进程还存在。这时子进程并没有被完全释放内存(在内核中的task_struct没被释放),该进程就成为僵尸进程。
②当僵尸进程的父进程结束后就会被init进程领养,最终被回收。
③避免僵尸进程的方法:
A.让僵尸进程的父进程来回收,父进程每隔一段时间来查询子进程是否结束并回收。调用wait或waitpid,通知内核释放僵尸进程。
B.采用信号SIGCHLD通知处理,并在信号处理程序中调用wait函数来通知释放僵尸进程。
C.让僵尸进程成为孤儿进程,由init进程回收。
【编程实验】僵尸进程的产生
//process_zombie.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
pid_t pid = fork();
if((pid) < 0){
perror("fork error");
exit(1);
}else if(pid == 0){//child process
printf("pid: %d, ppid: %d\n", getpid(), getppid());
exit(0);
}
//等待子进程结束并通知释放task_struct
//wait(0); //加上这句会通知内核释放子进程的task_struct,不会
//产生僵尸进程,可以取消注释来对比。
//试图产生僵尸进程
while(1){ //父进程继续循环,不退出。此时子进程未被完全
//释放而成为僵尸进程
sleep(1);
}
return 0;
}

浙公网安备 33010602011771号