Linux 进程等待

在2号手册里查wait()。wait()等待任意一个子进程的状态。

wait()等待成功会返回该子进程的id,返回失败会返回-1:

小实验 子进程的退出码

子进程执行work(),父进程wait子进程。

子进程跑完5秒之后就exit(0)退出。

子进程跑的时候是run状态

当子进程跑完,父进程接收到子进程的状态,即僵尸状态,然后父进程会跑10秒,10秒过后父进程也结束进程。

代码如下:

cpp 复制代码
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>


void work()
{
    int cnt=5;    
    while(cnt--)    
    {    
    
    printf("子进程开始启动:pid:%d,ppid:%d,cnt:%d\n",getpid(),getppid(),cnt);    
    sleep(1);    
    }    
}    
    
    
int main()    
{    
  
    sleep(10);    
    pid_t id=fork();    
   if(id==0)      //子进程
   {    
    
    work();                                                                                                                                        
    exit(0);    
   }    
   else //父进程
 {
    pid_t ret=wait(NULL);    
    if(ret==id)    
    {
        printf("wait success,pid:%d\n",getpid());
    }
}

    sleep(10);
    return 0;

 }
~

结论:子进程在跑,父进程就要进行阻塞等待。等子进程跑完,父进程才wait sucess,总结如下:

waitpid()

用法:

三个参数,重点讲一下 stauts

status是输出型参数,所谓输出型参数需要用户自己定义变量,然后传参,操作系统接收这个参数经过操作之后再返回给用户级变量

如下,定义一个int型变量,变量名为status,取地址传参,然后等如果父进程等待子进程之后就把status的值打印出来看看:

结果如下:

status是一个整形,有32位,分为高八位和低八位:

如果进程正常退出,就返回低八位的0,高八位的退出状态。

如果异常退出,就返回低七位的终止信号,为什么不是低八位呢? 低八位的第一位是core dump标志,所以只返回低七位。

如下,我们把子进程的退出码改为exit(10),再让父进程去等待:
运行结果:status为2560。

因为退出码10的二进制为1010,又因为异常所以在高八位,如下:

转化为十进制就是2560;








exit sign为stautus的信号退出码,exit code为status的进程退出码:

cpp 复制代码
printf("wait success,pid:%d,status返回码:%d, 

exit sign:%d    ,exit code:%d\n",getpid(),ret,

status&0x7F,(status>>8)&0xFF);      

为什么exit sign是 status&0x7F?

因为信号退出码在低七位 7是3个1,F是4个1,合起来就是7个1,&7个1就把低七位保留,其他位全变0

同理,exit code为高八位

运行结果:

退出信号为0,退出码为10、

如果我们把子进程的退出码改为正常退出码,即0,再跑,就会退出信号为0,退出码为0:

我们给子进程写一个除0错误:

退出信号会显示8:

我们让子进程出现空指针错误:

退出信号为11:11就是段错误:

第二个实验 手动退出

我们让子进程不要退出了,一直运行:

此时运行之后子进程就会一直跑,然后我们输入kill -9 pid终止进程,进程退出信号会显示9:

小结

父进程得到子进程的退出结果实际上是调用stautus这个整型变量,可以用一个指针解引用即可得到status。

WIFEXITED WEXITSTAUS

用这两个宏就我们就可以不用关注返回值,宏会自己获取子进程的返回值。

调用WIFEXITED获取是否正常退出,如果为假,直接输出else里面的异常。

如果为真,就调用WEXITSTAUS获取子进程的退出码并打印出来。

我们可以先搞一个异常出来,把子进程死循环:

运行:

我们再把子进程改为正常的再运行:

非阻塞轮巡/非阻塞等待

与阻塞式等待相对。

阻塞式等待父进程什么事情也不干,就在那等着子进程返回值。

阻塞式等待可以干自己的事情,等子进程返回的时候接收一下就可以了。

相关推荐
繁依Fanyi7 分钟前
简易安卓句分器实现
java·服务器·开发语言·算法·eclipse
C-cat.7 分钟前
Linux|环境变量
linux·运维·服务器
慧都小妮子18 分钟前
Spire.PDF for .NET【页面设置】演示:打开 PDF 时自动显示书签或缩略图
java·pdf·.net
yunfanleo21 分钟前
docker run m3e 配置网络,自动重启,GPU等 配置渠道要点
linux·运维·docker
m512722 分钟前
LinuxC语言
java·服务器·前端
烦躁的大鼻嘎23 分钟前
模拟算法实例讲解:从理论到实践的编程之旅
数据结构·c++·算法·leetcode
IU宝26 分钟前
C/C++内存管理
java·c语言·c++
瓜牛_gn27 分钟前
依赖注入注解
java·后端·spring
hakesashou28 分钟前
Python中常用的函数介绍
java·网络·python
佚先森37 分钟前
2024ARM网络验证 支持一键云注入引流弹窗注册机 一键脱壳APP加固搭建程序源码及教程
java·html