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获取子进程的退出码并打印出来。

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

运行:

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

非阻塞轮巡/非阻塞等待

与阻塞式等待相对。

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

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

相关推荐
penguin_bark1 分钟前
69. x 的平方根
算法
这可就有点麻烦了11 分钟前
强化学习笔记之【TD3算法】
linux·笔记·算法·机器学习
救救孩子把11 分钟前
深入理解 Java 对象的内存布局
java
DY009J12 分钟前
深度探索Kali Linux的精髓与实践应用
linux·运维·服务器
落落落sss14 分钟前
MybatisPlus
android·java·开发语言·spring·tomcat·rabbitmq·mybatis
苏宸啊17 分钟前
顺序表及其代码实现
数据结构·算法
万物皆字节19 分钟前
maven指定模块快速打包idea插件Quick Maven Package
java
lin zaixi()20 分钟前
贪心思想之——最大子段和问题
数据结构·算法
FindYou.21 分钟前
C - Separated Lunch
算法·深度优先
程序员-珍23 分钟前
虚拟机ip突然看不了了
linux·网络·网络协议·tcp/ip·centos