Linux进程控制——进程等待

文章目录

进程等待

进程等待的过程其实是父进程等待子进程死亡的过程

进程等待的必要性

如果子进程退出,父进程不进行处理,子进程会变成僵尸进程,有内存泄漏的风险

僵尸进程只有父进程有权处理,其他指令对其都没有效果了

父进程创建子进程是为了完成某项任务,当子进程结束后,父进程有必要了解任务完成的如何

父进程需要对子进程进行回收

进程等待的方法

waitpid系统调用的返回值是pid_t,如果等待成功则返回进程pid,失败则返回-1

这个函数有三个参数,第一个参数是pid_t pid,表示需要等待的进程id,输入-1表示等待任一子进程结束

第二个参数是int* stat_loc,这是一个输出型参数,采用指针的方法获取子进程退出状态,如果我们不关心这个状态直接传入NULL即可

第三个参数是int options,默认为0,代表阻塞等待,也有非阻塞等待的情况

还有一个wait的系统调用,只有第二个参数,就相当于waitpid的默认使用情况

c 复制代码
#include<sys/wait.h>
#include<stdlib.h>
#include<stdio.h>

int main()
{
    pid_t id = fork();
    if(id==0)
    {
        int count = 5;
        while(count)
        {
            printf("%d: 这是一个子进程,pid为:%d\n", count, getpid());
            count--;
            sleep(1);
        }
        exit(0);
    }
    waitpid(id,NULL,0);
    printf("等待子进程\n");
    return 0;
}

我们知道的是,当子进程创建出来之后,父进程是不会进入到判断语句中的,而且也没有打印等待子进程,而是一直在执行waitpid这一行,是一直等到子进程执行完毕之后才继续执行的

status参数

父进程想要了解子进程的退出码和推出信号就需要用到这个输出型参数status

而退出码和退出信号是两个数据,怎么只用一个参数来表示,这其实就用到了位图的思想,用低八位表示异常终止的信号,剩下八位表示退出的状态

画出来就是这样的

终止信号的最高位是一个core dump标志,我们暂时先不研究

因此我们就可以通过位运算来获取退出码和终止信号

退出码是(status >> 8) & 0xFF

终止信号是status & 0x7F

我们可以手动设置一下退出码来进行验证

c 复制代码
#include<sys/wait.h>
#include<stdlib.h>
#include<stdio.h>

int main()
{
    pid_t id = fork();
    int status = 0;
    if(id==0)
    {
        int count = 5;
        while(count)
        {
            printf("%d: 这是一个子进程,pid为:%d\n", count, getpid());
            count--;
            sleep(1);
        }
        exit(21);
    }
    waitpid(id,&status,0);
    printf("等待子进程\n");
    printf("退出码:%d; 终止信号:%d\n",(status>>8)&0xFF),status&0x7F;
    return 0;
}

option参数

option参数的默认值为0,表示阻塞等待,就是说父进程啥也不干,就等着子进程结束,那如果想让父进程可以在等待的时候做自己的事情,就需要用一个宏定义WNOHANG

意思是 waiting no hang 父进程会继续运行下面的代码,因为waitpid的返回值是进程退出的pid,我们也就可以用这个来判断,子进程是否结束

然后写一个循环访问即可

例如

c 复制代码
#include<sys/wait.h>
#include<stdlib.h>
#include<stdio.h>

int main()
{
    pid_t id = fork();
    if(id==0)
    {
        int count = 5;
        while(count)
        {
            printf("%d: 这是一个子进程,pid为:%d\n", count, getpid());
            count--;
            sleep(1);
        }
        exit(21);
    }
    while(1)
    {
        int wait = waitpid(id,NULL,WNOHANG);
        if(wait==id)
        {
            printf("子进程退出,id为%d\n",wait);
            break;
        }
        else if(wait==0)
        {
            printf("子进程未退出\n");
        }
        else
        {
            perror("waitpid");
            exit(1);
        }
        sleep(1);
    }
    return 0;
}
相关推荐
2603_965148113 小时前
家居百货蓝海:API挖掘高复购率生活小商品
大数据·服务器·人工智能·python·生活
上学的小垃圾6 小时前
基于docker安装MySQL(openEuler系统)
linux·mysql·docker·容器
cui_ruicheng7 小时前
LangChain 应用开发(十四):Agent 上下文与记忆机制
服务器·人工智能·python·langchain
一直C7 小时前
Linux网络编程|HTTP协议详解(报文、请求方法、状态码)
linux·http·wireshark·vim·visual studio
Brilliantwxx10 小时前
【Linux】 进程(10) 进程控制深度解析:创建、终止与等待
linux·运维·服务器·c语言·开发语言·网络
ai小陈10 小时前
FramePack图生视频云端部署实战:从单图输入到视频输出的完整流程
服务器·人工智能·安全·ai·音视频·gpu算力
欧米欧10 小时前
Linux基础指令上
linux·运维·服务器
ARM|X86+FPGA工业主板厂家11 小时前
基于嵌入式 GPU 的智能服务机器人
linux·运维·arm开发·fpga开发·机器人
sulikey12 小时前
Linux 粘滞位(Sticky Bit)完全指南:为什么共享目录需要“防删除“?
linux·服务器
mengge.cloud12 小时前
网络技术基础小白教程
linux·服务器·网络·云计算