Linux系统编程(二)孤儿进程和僵尸进程

本文深入探讨了Linux系统编程中的关键概念,包括exec函数族的使用,它们如何替换当前进程空间,并详细阐述了孤儿进程和僵尸进程的产生与处理方式。wait和waitpid函数的讲解则揭示了如何有效地管理子进程,特别是waitpid的非阻塞特性。通过示例代码展示了这些函数在实际操作中的应用。


一、exec函数族

exec函数使用时,改程序的用户空间的代码和数据会被新程序给替代,会从新程序的启动例程开始。调用exec并不创建新进程,调用前与调用后进程的id并不会改变

1.exec函数

代码如下(示例):

#include <cstdio>
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>



int main()
{
    pid_t pid, wpid;
    int n = 3;
    int i;
    for (i = 0; i < n; i++)
    {
        pid = fork();
        if (pid == 0)
        {
            break; //子进程就退出
        }


    }
    //主进waitpid回收
    if (i == n)
    {
        sleep(n);
        printf("-----parent process ");
        do 
        {
            wpid = waitpid(-1,NULL,WNOHANG);
        } while (wpid==0);


    }
    else
    {
        sleep(i);
        printf("-----%dth child process \n",i+1);
        if (i == 0)
        {
            //execlp("ps","ps",NULL);

        }
        else if (i == 1)
        {
            printf("child process's pid = %d \n",getpid());
            execl("./hello","hello",NULL);
        }

    }

    return 0;
}

在这里插入图片描述

二、孤儿进程和僵尸进程

孤儿进程:父进程先于子进程结束,子进程就变成孤儿进程,子进程的父进程就变成了init进程,由init进程自动回收子进程

僵尸进程:子进程终止后,父进程并没有进行回收,子进程残留资源(PCB)仍保留在内核中,变成僵尸进程

杀死僵尸进程方法:
1.杀死父进程,子进程就变成孤儿进程,由init进程自动回收
2.使用wait和waitpid函数回收僵尸进程

三、wait和waitpid

1.wait函数

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

#include <cstdio>
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>
int main()
{
    pid_t pid, wpid;
    int status;

    pid = fork();

    if (pid == 0)
    {
        
        printf("----child, my parent=%d,going to sleep 3s\n",getppid());
        sleep(3);
        printf("---------------child die ---------------------\n");
        
    }
    else if (pid > 0)
    {
        
        wpid = wait(&status);
        if (wpid == -1)
        {
            perror("wait erroe:");
            exit(1);
        }
        //进程正常结束
        if (WIFEXITED(status))
        {
            printf("child exit with %d\n",WEXITSTATUS(status));

        }
        //异常退出的信号
        if (WIFSIGNALED(status))
        {
            printf("child killed by %d \n", WTERMSIG(status));
        }

        while (1)
        {
            printf("I am parent,pid= %d,myson=%d\n",getpid(),pid);
            sleep(1);
        }


    }

    return 0;
}

在这里插入图片描述
在这里插入图片描述

子进程休眠三秒,主进程因为有wait会阻塞,等子进程执行完毕后,才会执行主进程的代码,同时对其进行回收。
PS注意:如果同时创建多个进程,wait函数会等待第一个执行完成的进程并对其回收,这个进程可能是多个进程里的任意一个。

2.waitpid函数

作用同wait,但可指定pid进程清理,可以不阻塞

#include <cstdio>
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>


int main()
{
    pid_t pid,wpid;
    int n = 5;
    int i;
    for (i = 0; i < n; i++)
    {
        pid = fork();
        if (pid==0)
        {
            break;    //子进程退出
        }


    }
    //主进程逻辑
    if (n == i)
    {
        sleep(n);
        printf("I am parent ,pid = %d\n",getpid());
        do
        {
            wpid=waitpid(-1, NULL, WNOHANG);//使用WNOHANG模式,主进程不会阻塞,子进程仍在运行返回0
            //if wpid ==0说明进程在运行
            sleep(1);
            

        } while (wpid==0);
        while (1)
        {

        }
    
    
    }
    else 
    {
        sleep(i);
        printf("I'm %dth child ,pid = %d , gpid = %d\n",i+1,getpid(),getgid());
        exit(1);
    }




    printf("hello from %s!\n", "test_waitpid");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chenshida_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值