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;
}
相关推荐
不知几秋3 小时前
数字取证-内存取证(volatility)
java·linux·前端
珊珊而川5 小时前
ChatPromptTemplate创建方式比较
服务器·langchain
欧先生^_^7 小时前
Linux内核可配置的参数
linux·服务器·数据库
若风的雨7 小时前
【deekseek】P2P通信路由过程
服务器·网络协议·p2p
海尔辛7 小时前
学习黑客5 分钟读懂Linux Permissions 101
linux·学习·安全
Python私教7 小时前
征服Rust:从零到独立开发的实战进阶
服务器·开发语言·rust
王RuaRua8 小时前
[数据结构]5. 栈-Stack
linux·数据结构·数据库·链表
曼岛_8 小时前
[架构之美]linux常见故障问题解决方案(十九)
linux·运维·架构
tan180°8 小时前
Linux进程信号处理(26)
linux·c++·vscode·后端·信号处理
大神的风范8 小时前
从0开始学linux韦东山教程第三章问题小结(4)
linux·服务器