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

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

运行:

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

非阻塞轮巡/非阻塞等待

与阻塞式等待相对。

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

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

相关推荐
adam_life6 分钟前
http://noi.openjudge.cn/——2.5基本算法之搜索——200:Solitaire
算法·宽搜·布局唯一码
iuyou️23 分钟前
Spring Boot知识点详解
java·spring boot·后端
北辰浮光25 分钟前
[Mybatis-plus]
java·开发语言·mybatis
一弓虽35 分钟前
SpringBoot 学习
java·spring boot·后端·学习
南客先生39 分钟前
互联网大厂Java面试:RocketMQ、RabbitMQ与Kafka的深度解析
java·面试·kafka·rabbitmq·rocketmq·消息中间件
ai大佬42 分钟前
Java 开发玩转 MCP:从 Claude 自动化到 Spring AI Alibaba 生态整合
java·spring·自动化·api中转·apikey
我想进大厂1 小时前
图论---朴素Prim(稠密图)
数据结构·c++·算法·图论
我想进大厂1 小时前
图论---Bellman-Ford算法
数据结构·c++·算法·图论
AIGC大时代1 小时前
高效使用DeepSeek对“情境+ 对象 +问题“型课题进行开题!
数据库·人工智能·算法·aigc·智能写作·deepseek
光而不耀@lgy1 小时前
C++初登门槛
linux·开发语言·网络·c++·后端