当前位置: 首页 > news >正文

Linux(9)——进程(控制篇——下)

三、进程等待

1)进程等待的必要性

  1. 之前提过子进程退出,父进程如果不读取子进程的退出信息,就可能造成“僵尸进程”的问题,从而造成内存泄漏的问题。
  2. 再者,一旦子进程进入了僵尸状态,那就连kill -9都杀不亖他,因为没有谁能够杀亖一个死去的进程。
  3. 最后,父进程创建子进程是要获取子进程的完成任务的情况的。
  4. 父进程需要通过等待的方式来回收子进程的资源,获取子进程的退出信息。

2)获取子进程的status

下面进程等待使用的两个方法wait方法和waitpid方法都有一个status参数,这是一个输出型参数(输出型参数是函数中用于返回结果或修改调用者变量的参数,通常通过引用或指针实现。如void func(int *output)。),由操作系统进行填写。

如果向status中传递的是NULL,那就表示用户不关心子进程的退出状态。否则,操作系统会根据该参数,将子进程的退出信息反馈给父进程。

status不能简单的当作整形来看待,可以当作位图来看待,具体细节如下图(只研究status低16比特位):

我们从图中可见,status的低16比特位中,高8位表示进程的退出状态,即退出码。当进程被信息杀亖时,则低7位表示终止信息,第8位时core dump标志。

我们可以通一系列的位操作来得出进程的退出码和退出信号。

exitcCode = (status >> 8) & 0xFF; //退出码exitSignal = status & 0x7F;

对于这两个操作,系统提供了两宏来获取退出码以及退出信号。分别是:

  • WIFEXITED(status):用于查看是否是正常退出,本质是检查是否收到信号。
  • WEXITSTATUS(status):用于获取进程的退出码。
exitNormal = WIFEXITED(status); //是否正常退出exitCode = WEXITSTATUS(status); //获取退出码

敲黑板:

当一个进程是非正常退出的时候,那么该进程的退出码将毫无意义。

3)进程的等待方法

wait方法

函数类型:pid_t wait(int* status);

返回值:成功返回被等待进程pid,失败返回-1。

参数:输出型参数,获取子进程退出状态,不关心则可以设置成为NULL 

作用:等待任意子进程 

创建子进程后,父进程使用wait方法等待子进程,直到子进程的退出信息被读取,我们可以写个代码验证一下:

#include <stdio.h>    
#include <stdlib.h>    
#include <unistd.h>    
#include <sys/wait.h>    
#include <sys/types.h>    int main()    
{    pid_t id = fork();    if(id == 0){ //子进程    int count = 10;    while(count--)    {    printf("我是子进程,PID:%d, PPID:%d\n", getpid(), getppid());    sleep(1);    }    exit(0);    }    //父进程                                                                                                                                                               int status = 0;    pid_t ret = wait(&status);    if(ret > 0){    printf("等待成功...\n");    if(WIFEXITED(status)){    printf("退出码:%d\n", WEXITSTATUS(status));    }    }    sleep(3);    return 0;    
}

然后我们可以在开一个会话用来监控进程的状态:

while :; do ps axj | head -1 && ps axj | grep test | grep -v grep;echo "============================================================";sleep 1;done

 在下面这图中我们可以看到,当子进程退出,父进程读取到了子进程的退出信息时,子进程就不会变成僵尸状态了。

waitpid方法 

函数原型:pid_t waitpid(pid_t pid, int *status, int options);

返回值:

  1. 当正常返回的时候waitpid返回收集到的子进程的进程ID;
  2. 如果设置了选项WNOHANG(option),而调用中waitpid发现没有已退出的子进程可收集,则返回0;
  3. 如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在; 

参数:

  1. pid:当pid=-1,等待任意一个子进程,与wait等效。当pid>0.等待其进程ID与pid相等的子进程。
  2. status:输出型参数,用来获取子进程的退出状态,不关心可以设置成NULL。
  3. options:默认为0,表示阻塞等待;当设置为WNOHANG时,若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若正常结束,则返回该子进程的ID。

返回值:等待任意子进程(可以指定)退出 

我们可以写个代码来验证一下,创建子进程后,父进程可以使用waitpid函数一直等待子进程,直到子进程退出后读取子进程的退出信息。

#include <stdio.h>    
#include <stdlib.h>    
#include <unistd.h>    
#include <sys/wait.h>    
#include <sys/types.h>    int main()    
{    pid_t id = fork();    if(id == 0){ //子进程    int count = 10;    while(count--)    {    printf("我是子进程,PID:%d, PPID:%d\n", getpid(), getppid());    sleep(1);    }    exit(0);    }    //父进程    int status = 0;    //pid_t ret = wait(&status);    pid_t ret = waitpid(id, &status, 0);    if(ret >= 0){    printf("等待成功...\n");    if(WIFEXITED(status)){    printf("退出码:%d\n", WEXITSTATUS(status));    }else{    printf("被信号杀?:%d\n",status & 0x7F);    }                                                                            }    sleep(3);    return 0;    
}

在父进程运行过程中,我们可以使用kill -9命令来将子进程杀亖,这个时候父进程也能成功等待子进程。

敲黑板:

被信号杀亖的进程的退出码是没有意义的。

多进程创建以及等待的代码模型  

上面演示的都是父进程的创建以及等待一个子进程,那么接下来我们可以同时创建多个子进程,然后让父进程进程依次等待子进程退出。

下面我们可以同时创建10个子进程,同时将子进程的pid放到一个id数组中,并将这10个子进程的退出时的退出码设置为该子进程pid对应数组中的下标,之后父进程使用waitpid等待这10个子进程。

 

 

相关文章:

  • 电磁器件的“折纸革命“:牛津《Sci. Reports》发布剪纸超材料
  • gitlib 常见命令
  • C++写入CSV的操作读取、写入、追加以及文件删除
  • Unsafe.putOrderedInt与Volatile
  • 软件需求文档如何做精确度度量
  • 告别集成泥潭,拥抱松耦合、高弹性的现代化应用-Amazon EventBridge
  • 需求可测试性评价
  • Tomcat JK2 连接器安装教程:jakarta-tomcat-connectors-jk2-src-current.tar.gz 配置步骤详解
  • 第2章-12 输出三角形面积和周长(走弯路解法)
  • yolov8添加注意力机制
  • 铁路行业数字化应用建设方案
  • 企业微电网能效管理平台设计说明
  • 【容器docker】启动容器kibana报错:“message“:“Error: Cannot find module ‘./logs‘
  • Qt中使用正则表达式来提取字符串
  • TreeMap、TreeSet和HashMap、HashSet
  • PHP 垃圾回收机制解析与应用案例
  • Java线程安全解决方案全面指南
  • Linux入门——入门常用基础指令(3)
  • 贫血模型与充血模型:架构设计的分水岭
  • 分库分表内容
  • 现在个人做网站还能盈利/西安优化外
  • 电子商务网站建设期末作业/网站优化的方法有哪些
  • 海珠网站建设公司/怎样在百度上免费做广告
  • 网站开发英文术语/seo优化搜索推广
  • 网站建设网络推广首选公司/深圳做网站的公司
  • 伪静态网站入侵/申京效率值联盟第一