博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux进程浅析(下)
阅读量:3748 次
发布时间:2019-05-22

本文共 4678 字,大约阅读时间需要 15 分钟。

Linux进程浅析下

  1. 僵尸进程
  2. wait和waitpid函数

僵尸进程

看到僵尸二字很多时候我们都会想到林正英饰演的僵尸道长系列,僵尸都是一群失去了生命,但是却可以活动的尸体吧,其实在linux内核中其实也相似,这类进程也是失去生命,但是却没有被彻底回收掉的

一批进程。

僵尸进程的概念:子进程结束但是没有完全释放内存,在内核中(task_struct没有释放),该进程就是僵尸进程当僵尸进程的父进程结束后就会被init进程领养,最终被回收避免僵尸进程:1:让僵尸进程的父进程来回收,父进程每隔一段时间来查询子进程是否回收,调用wait()或者waitpid(),通知内核释放僵尸进程。2:采用信号SIGCHLD(singalchild)通知处理,并在信号处理程序中调用wait函数,3:让僵尸进程成为孤儿进程,由init进程回收;

直接上代码吧,打造属于我们自己的僵尸进程,代码类似打造我们自己的孤儿进程,如果想了解什么叫孤儿进程,请参考,里面讲解了孤儿进程

#include
#include
#include
#include
int main(int argc,char * argv[]){ pid_t pid; pid = fork(); if(pid <0){ perror("fork error\n"); exit(EXIT_FAILURE); }else if(pid > 0){ }else{ printf("getpid:%d,getppid:%d\n",getpid(),getppid()); exit(1); } while(1){ sleep(1); } return 0;}

执行结果如下所示:

这里写图片描述
子进程结束了,但是父进程处于一种等待状态,这个时候打开另外一个终端就可以看到后台的这个子进程有没有继续在运行了
这里写图片描述
从这里就可以看到,后台其实还是有一个process_zombie进程好为23863的这样的一个进程在运行并且其有一个状态为Z+,说明其子进程为僵尸状态,而父进程23862处于S+状态,说明其处于的是一种可中断的等待状态
那下面就简单了解下,怎么通过父进程来关闭释放掉僵尸进程。
也就是wait和waitpid函数的使用

wait和waitpid函数

wait函数和waitpid函数:#include
#include
pid_t wait(int *status);返回:成功返回子进程ID,出错返回-1功能:等待子进程退出并且回收,防止孤儿进程产生pid_t waitpid(pid_t pid,int *status,int options);返回:成功返回子进程ID,出错返回-1功能:wait函数的非阻塞版本区别:在一个子进程终止前,wait函数阻塞waitpid有一个选项,可使调用者不阻塞waitpid等待一个指定的子进程,而wait等待所有的子进程,返回任何子进程的状态status参数:为空时,代表任意状态结束的子进程,若不为空,则代表指定状态结束的子进程;检查wait和waitpid函数返回终止状态的宏;WIFEXITED/WEXITSTATUS(status)若子进程正常终止,则为真WIFSIGNALED/WTERMSIG(status)若为异常终止子进程返回的状态,则为真WIFSTOPED/WSTOPSIG(status)若子进程在终止前是否暂停过,如果暂停为真,实例代码如下所示:if(WIFEXITED(status)){ printf("%d",WEXITSTATUS(status)); }else if(WIFSTOPED(status)){ printf("%d",WTERMSIG(status));}else if(WIFSTOPED(status)){ printf("%d",WSTOPSIG(status));}else{ printf("unknow sig\n");}option参数WNOHANG 若由pid制定的子进程没有退出则立即返回,则waitpid不阻塞,此时其返回值为0;WUNTRACED若某实现支持作业控制,则由pid制定的任一子进程状态已暂停,且其状态自暂停以来还未报告过,则返回其状态实例参数如下所示:do{ pid = waitpid(pid,&status,WNOHANG | WUNTRACED); if(pid == 0) sleep(1);}while(pid==0) exit(3); //exit(0);如果为0 ,则为正常终止,非0为异常终止状态;使用kill -l的时候可以查看到Linux系统的所有信号关于waitpid的pid参数传递: 若pid == -1 等待任意一个子进程 若pid > 0 等待其与其进程id相匹配的子进程结束 若pid == 0 等待其组id等于调用进程的组ID的任意子进程 若pid < -1 等待其组id等于pid绝对值的任一子进程

下面的代码是关于wait函数的:注意:wait函数是阻塞式的调用,即父进程会阻塞等待子进程的释放。

#include
#include
#include
#include
#include
void outStatus(int status);int main(int argc,char *argv[]){ pid_t pid = fork(); int status; if(pid < 0){ perror("fork error"); exit(1); }else if(pid > 0){ //父进程执行 pid_t child_pid = wait(&status); outStatus(status); }else { //子进程执行 printf("pid:%d,ppid:%d\n",getpid(),getppid()); exit(3); //异常终止法 //int num1 = 3 ,num2 = 0; //int k = num1 / num2; //printf("k = :%d\n",k); //暂停终止法 //pause(); } return 0;} void outStatus(int status){ if(WIFEXITED(status)){ printf("waitexist:%d\n",WEXITSTATUS(status)); }else if(WIFSIGNALED(status)){ printf("waitsinglenal:%d\n",WTERMSIG(status)); }else if(WIFSTOPPED(status)){ printf("waitstop:%d\n",WIFSTOPPED(status)); }else { printf("unknow exit!\n"); }}

代码也是可以直接进行run的

下面了解一下waitpid这个函数,这个函数可以设置阻塞方式也可以设置非阻塞方式,记住如果要处理暂停状态的话,那么就必须要去使用waitpid来进行设置:

#include
#include
#include
#include
#include
#include
void outStatus(int status);int main(int argc,char * argv[]){ pid_t pid = fork(); int status; if(pid < 0 ){ perror("fork error\n"); exit(1); }else if(pid > 0){ //父进程执行的时间片 //专门处理进行过停止状态后的进程退出 do { pid = waitpid(pid,&status,WNOHANG | WUNTRACED); //说明子进程没结束 if(pid == 0){ sleep(1); } }while(pid == 0); outStatus(status); }else { //子进程执行的时间片,子进程做暂停操作 printf("getpid:%d getppid:%d\n",getpid(),getppid()); pause(); //或者将子进程进行永久睡眠 //int i = 0; //while(++i > 0){ // sleep(4); //} } return 0;}void outStatus(int status){ if(WIFEXITED(status)){ printf("exit :%d\n",WEXITSTATUS(status)); }else if(WIFSIGNALED(status)){ printf("singal:%d\n",WTERMSIG(status)); }else if(WIFSTOPPED(status)){ printf("stop:%d\n",WIFSTOPPED(status)); }else { printf("unknow exit!\n"); }}

可能在这里需要提到一点,就是linux系统信号相关的东西,在linux系统中。提供了相关信号,使用kill -l 进行查看。可以使用相关信号来对 进程做相应的处理,如下图所示

linux信号

具体的一下含义在linux内核中的信号相关部分,可以解释下,有点兴趣的可以自己简单搜一下。对应的是哪些含义的信号

最近相对来说也比较忙,事情也比较多,也遇到了可能作为程序员以来最不愿意看到的结果,所以有点小受挫,所以更的速度相对来说稍微慢了一点。当头一棒吧。内功还得继续修炼。

以上的代码都是可以直接进行run的。有兴趣的童鞋可以试着拷贝下去跑着玩,同时最近也想着建一个撸代码的群。也是一个学习群吧,寻找有志之士,希望能够相互学习,帮助,共同成长吧。认识的人不在多,在帮助有多深。,知识,技术本来就是一个交流的过程,只有交流,只有学习,也同时需要更多的努力,才能成为一个合格的程序员吧!!

qq群号为324652573

你可能感兴趣的文章
MySQL day12
查看>>
JSONP原理
查看>>
Vue.js学习笔记—插值的操作(1)
查看>>
CSS的四种方式实现水平居中
查看>>
RISC-V生态架构浅析(认识RISC-V)
查看>>
? 精美图文带你掌握 JVM 内存布局
查看>>
谈谈go.sum
查看>>
tls 1.2 example
查看>>
GitHub 计划登陆中国,将产生哪些影响与意义?
查看>>
2019 我是怎样熬过来的?
查看>>
【C++学习计划】深入浅出——变量作用域(Day3)
查看>>
策略模式
查看>>
Spring Boot 实战 入门
查看>>
关于web系统整体优化提速总结
查看>>
分布式文件系统 - fastDFS
查看>>
BUAA OO 2019 第一单元作业总结
查看>>
格网编码查询方案在项目运用上的进一步探索
查看>>
BUAA-OO-2019 第三单元总结
查看>>
Matlab策略模式
查看>>
架构整洁之道
查看>>