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

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

运行:

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

非阻塞轮巡/非阻塞等待

与阻塞式等待相对。

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

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

相关推荐
m0_74472493几秒前
Tomcat相关
java·tomcat
小许同学记录成长2 分钟前
网格简化算法 — Edge Collapse(边塌缩)
qt·算法
键盘上的猫头鹰4 分钟前
【Linux 基础教程(一)】概述、安装与网络配置:VMware + CentOS + NAT + XShell 远程连接
linux·网络·centos
凯瑟琳.奥古斯特5 分钟前
力扣1001网格照明解法
算法·leetcode·职场和发展
fengenrong8 分钟前
20260601
算法·深度优先·图论
枳实-叶9 分钟前
【Linux驱动开发】第18天:I2C驱动深度解析
linux·运维·驱动开发
晚笙coding10 分钟前
从“看起来像双指针”到真正的动态规划 —— 最长公共子序列
算法·动态规划
AugustRed11 分钟前
A2UI 完整学习指南(含 Java 后端 + 前端实战示例)
java·开发语言·前端
shandianchengzi13 分钟前
【记录】Ubuntu|Ubuntu 26.04 笔记本耗电过快,排查 省电过程
linux·运维·ubuntu
程序猿乐锅16 分钟前
【MySQL | 第五篇】 MySQL 性能分析:如何查询慢 SQL
java·sql·mysql