exit _exit wait waitpid

 

 

复制代码
/*

        #include <stdlib.h>

        void exit(int status);

        #include <unistd.h>

        void _exit(int status);

            参数:
                status:进程退出时的一个状态信息,由调用进程传给父进程

    孤儿进程
        父进程运行结束,但子进程还在运行,这样的子进程称为孤儿进程
        内核会把孤儿进程的父进程设置为init,init会循环的wait()它的已退出的子进程
    僵尸进程
        终止但未被回收的进程
        不能被kill -9 杀死
        办法:1、父进程要有义务使用  wait 和 waitpid来回收子进程 2、用ctrl c杀死父进程
        用户区的资源可以释放掉,但内核区的资源不能被释放
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{

    printf("Hello\n");
    printf("World");

    exit(0); // 会输出Hello\n World
    // _exit(0); // 只会输出Hello\n   因为exit和\n都会刷新IO缓冲区,_exit()不会






    return 0;
}
复制代码

 

wait

 

复制代码
/*
    wait 和 waitpid
        等待子进程结束
        功能一样,区别在于wait函数会阻塞,waitpid可以设置不阻塞,且能指定子进程
        调用init进程会被挂起,直到一个子进程退出或收到一个不能被忽略的信号

        #include <sys/types.h>
        #include <sys/wait.h>

        pid_t wait(int *wstatus);
        等于 waitpid(-1, &wstatus, 0);
        


        pid_t waitpid(pid_t pid, int *wstatus, int options);


        参数:
            pid:
                < -1 子进程group id等于绝对值的所有进程
                == -1 等待所有子进程
                == 0 所有子进程group id等于当前调用进程的group id
                > 0 指定进程
            wstatus:
                进程退出时的状态信息,传出参数
            options:
                0:阻塞
                其它,如WNOHANG:其余查看手册

        返回值:
            成功返回子进程id,
            options = WNOHANG返回0,表示还有子进程
            错误返回-1
        注意:
            一次wait或waitpid调用只能清理一个子进程,清理多个子进程应使用循环
*/

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

int main()
{

    // printf("Hello\n");
    // printf("World");

    // exit(0); // 会输出Hello\n World
    // // _exit(0); // 只会输出Hello\n   因为exit和\n都会刷新IO缓冲区,_exit()不会



    pid_t pid;
    
    // 创建5个子进程
    for(int i = 0; i < 5; i++)
    {
        pid = fork();
        if(pid == 0)
            break;
    }

    if(pid > 0)
    {
        while(1)
        {
            printf("i am parent, pid = %d \n", getpid());
            // int ret = wait(NULL);

            // 通过宏函数判断状态,获取的状态是由子进程的exit()和return传递
            int st;
            int ret = wait(&st);
            if(WIFEXITED(st))
            {
                printf("状态码为%d\n", WEXITSTATUS(st));
            }


            if(ret == -1)
                break;
            printf("wait child %d \n", ret);
            sleep(1);

        }
    }
    else
    {
        printf("i am child, pid = %d \n", getpid());

    }
    return 0;
}
复制代码

 

复制代码
    // 防止终止了多个进程,未决信号集只保存了一个信号
    while(1)
    {
        int ret = waitpid(-1, NULL, WNOHANG);
        if(ret == 0) // 还有子进程活着,但未终止
            break;
        else if(ret == -1) // 所有的子进程都回收了
        {
            break;
        }
        else
        {
            printf("%d recovery successfully\n", ret);
        }
    }
复制代码

 

 

 

 

posted @   WTSRUVF  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
历史上的今天:
2021-04-27 [每日一题]leetcode 938. 二叉搜索树的范围和
2019-04-27 博弈随笔(未完待续)
2019-04-27 Mergeable Stack ZOJ - 4016(list)
点击右上角即可分享
微信分享提示