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;
}
相关推荐
颇有几分姿色9 分钟前
深入理解 Linux 内存管理:free 命令详解
linux·运维·服务器
AndyFrank39 分钟前
mac crontab 不能使用问题简记
linux·运维·macos
筱源源1 小时前
Kafka-linux环境部署
linux·kafka
EricWang13581 小时前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
算法与编程之美2 小时前
文件的写入与读取
linux·运维·服务器
xianwu5432 小时前
反向代理模块
linux·开发语言·网络·git
Amelio_Ming2 小时前
Permissions 0755 for ‘/etc/ssh/ssh_host_rsa_key‘ are too open.问题解决
linux·运维·ssh
Ven%3 小时前
centos查看硬盘资源使用情况命令大全
linux·运维·centos
JaneJiazhao3 小时前
HTTPSOK:SSL/TLS证书自动续期工具
服务器·网络协议·ssl
萨格拉斯救世主4 小时前
戴尔R930服务器增加 Intel X710-DA2双万兆光口含模块
运维·服务器