僵死进程

2019-07-14 07:39发布

1、产生原因
     进程主体结束,但是其PCB没有释放
     PCB中记录进程的运行信息,进程结束时,PCB中有一个exit_code,保存进程的退出信息,进程退出信息如果没有被(父进程)处理,则PCB无法释放
     子进程结束,父进程未结束并且父进程未获取(处理)子进程的退出状态,从而子进程不得不保存退出码,所以整个PCB就无法释放
僵尸进程 int main() { pid_t pid=fork(); assert(pid!=-1); int n=0; char *s=NULL; //子进程 if(pid==0) { n=0; s="child pid"; } //父进程 else { n=5; s="---father----"; /* while(1) { sleep(2); printf("---father---- "); printf("father pid=%d,ppid=%d ",getpid(),getppid()); }*/ } int i=0; for(;i 查找僵尸进程 ps aux|grep defunct 在这里插入图片描述
2、父进程如何处理子进程的退出状态:
     用wait函数将调用者阻塞,直到某个子进程终结,故父进程可调用wait函数回收其僵尸子进程。
pid_t wait(int *reval); 阻塞
调用一次,只能处理一个子进程的僵死状态
wait函数会阻塞,直到任意一个子进程结束
返回值:-1,回收失败,已经没有子进程了
              >0,回收是子进程对应的pid
reval:获取到子进程的退出码 void fun(int sign) { pid_t pid=wait(NULL); printf("pid=%d ",pid); } int main() { signal(SIGCHLD,fun); pid_t n=fork(); assert(n!=-1); if(n==0) { printf("child start:%d ",getpid()); sleep(2); printf("chile over "); } else { printf("father start: "); while(1) { sleep(1); printf("father running "); } sleep(100); printf("father over "); } } waitpid
    如果在调用waitpid()函数时,当指定等待的子进程已经停止运行或结束了,则waitpid()会立即返回;但是如果子进程还没有停止运行或结束,则调用waitpid()函数的父进程则会被阻塞,暂停运行。
pid_t waitpid(pid_t pid,int *reval,int flag); 非阻塞
pid:
     pid>0:某个子进程的pid
     pid==-1 回收所有的子进程
         循环回收
         while((wpid=waitpid(-1,&status,WNOHANG)));
     pid==0 回收当前进程组所有的子进程
     pid<0 子进程的pid取反(加减号)
flag
     0-waitpid阻塞
     WNOHANG非阻塞
返回值:
     -1 回收失败
     >0 回收子进程的pid
     如果为非阻塞 =0:子进程处于运行状态
返回值 阻塞运行:函数调用,只要条件不满足,则函数不成立
非阻塞运行:函数调用,无论任何情况,函数都会立即返回
信号:系统预先定义好的某些特定的事,事件可以被产生,也可以被接收,产生和接收事件的主体都是进程。
     /usr/include/bits/signum.h
1、收到信号后,进程的行为如何设置。
信号的响应方式:
     忽略    SIG_IGN
     默认    SIG_DFL
     自定义   用户函数 void signal_fun(int sign);
修改信号的响应方式
typedef void (*fun)(int);
Fun signal(int signum,Fun fun);
SIGKILL不允许修改其响应方式
     进程接收到信号后,main函数中的执行体会被暂停,先调用信号处理函数,执行完后,main函数的执行体会被恢复接着执行。