wait/waitpid函数等待子进程状态发生改变

本文详细介绍了Linux系统中用于进程通信和管理的wait和waitpid函数,包括它们的使用场景、参数解释以及代码示例,阐述了如何等待子进程状态改变并释放资源,防止僵尸进程的产生。同时,讨论了进程的退出状态和信号对进程的影响。
摘要由CSDN通过智能技术生成

 

🎊【进程通信与并发】专题正在持续更新中,进程,线程,IPC,线程池等的创建原理与运用✨,欢迎大家前往订阅本专题,获取更多详细信息哦🎏🎏🎏

🪔本系列专栏 -  ​​​​​​并发与进程通信

🍻欢迎大家  🏹  点赞👍  评论📨  收藏⭐️

📌个人主页 - 勾栏听曲_0的博客📝

🔑希望本文能对你有所帮助,如有不足请指正,共同进步吧🏆

🎇春山多胜事,赏玩夜忘归。掬水月在手,弄花香满衣。📈

目录

wait/waitpid函数

wait函数

接口

代码实例

waitpid函数

接口

代码示例


wait/waitpid函数

这两个函数用来等待某个(些)子进程的状态发生改变的,等待的状态

        发生改变有三种情况:   

            a.子进程退出(正常退出):main函数返回值/exit/_exit 
            b.子进程被信号中止 
            //c.子进程被信号唤醒(blocking -> ready)

        在子进程正常退出(a)情况,调用wait/waitpid可以释放子进程的资源,假如没有调用wait/waitpid,那么子进程退出后,就会变成僵尸进程(zomble)

        一个进程退出,操作系统会释放他大部分的资源,但是有一部分必须留给他的父进程去释放。如果一个进程退出了,但是它父进程没有wait/waitpid,这个进程就会变成僵尸进程:已经死掉了 但是资源没有被完全释放掉。

        假如一个子进程的状态已经发生改变,那么调用wait/waitpid就会立即返回,否则会阻塞调用进程直到某个子进程的状态发生改变或被信号中断。

wait函数

        pid_t wait(int *wstatus); 用来等待任意一个子进程退出的状态

        函数参数 

                int *wstatus  //指针。指向的空间,用来保存子进程的退出信息的(怎么死的,退出码等等)

                wstatus 用来保存退出的子进程的退出信息的,退出信息保存在一个整数。

                我们可以用如下宏来解析子进程的退出信息:  

                        WIFEXITED(wstatus)
                        return  true 
                        假如该子进程是正常退出的(main返回/exit/_exit)
                        只有子进程正常退出,它才会有退出码!!!

                    WEXITSTATUS(wstatus)

                        返回子进程的退出码,只有子进程正常退出 
                        这个宏才有意义,
                        把进程的退出码, unsigend char 来看待 

                WIFSIGNALED(wstatus)

                    return true  
                    假如子进程是被信号干掉的
                    ...

接口

头文件  

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

        函数功能

            等待子进程退出 

        函数原型 

            pid_t wait(int *wstatus);

代码实例

#include <stdio.h>  
#include <stdlib.h>  
#include <unistd.h>  
  
int main() {  
    pid_t pid = fork();  
  
    if (pid == -1) {  
        perror("fork");  
        exit(EXIT_FAILURE);  
    } else if (pid == 0) {  
        // child process  
        printf("Child process is running.\n");  
        sleep(5);  
        printf("Child process is exiting.\n");  
        exit(EXIT_SUCCESS);  
    } else {  
        // parent process  
        printf("Parent process is running.\n");  
        printf("Child process is running.\n");  
        printf("Child process is exiting.\n");  
        sleep(5);  
        printf("Parent process is exiting.\n");  
        exit(EXIT_SUCCESS);  
    }  
}

waitpid函数

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

                pid_t pid   //指定要等待的进程或进程组

                            pid == -1,表示等待任意的子进程退出
                            pid == 0,表示等待与调用进程同组的任意子进程

                            "进程组" 

                                就是一组进程。每个进程必须会属于某一个进程组。
                                并且每个进程组,都会有一个组长进程,一般来说, 
                                创建这个进程组的进程为组长,进程组有一个组id,
                                这个组id,就是组长进程的pid,
                            pid < -1 表示等待组id等于 pid绝对值的那个组的任意子进程

                            如:  

                                pid == -128  
                                等待进程组 128那个组内的任意的子进程 

                            pid > 0,表示等待指定的子进程(其进程id为pid的那个进程)

                int *wstatus  //同上。  

                
                int options     //等待选项 

                             0:表示阻塞等待 
                             WNOHANG:非阻塞,假如没有子进程退出,则立即返回。

                wait(&wstatus)

                    <=> waitpid(-1,&wstatus,0);

            函数返回值 

            成功:返回退出的那个子进程的进程id   
            失败:返回-1,同时errno被设置。

接口

头文件  

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

        函数功能

            等待子进程退出 

        函数原型 

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

代码示例

#include <stdio.h>  
#include <stdlib.h>  
#include <unistd.h>  
  
int main() {  
    pid_t pid, sid;  
  
    // fork() 创建子进程  
    pid = fork();  
  
    if (pid == -1) {  
        perror("fork");  
        exit(EXIT_FAILURE);  
    } else if (pid == 0) {  
        // child process  
        printf("Child process is running.\n");  
        sleep(5);  
        printf("Child process is exiting.\n");  
        exit(EXIT_SUCCESS);  
    } else {  
        // parent process  
        printf("Parent process is running.\n");  
        printf("Child process is running.\n");  
        printf("Child process is exiting.\n");  
        sleep(5);  
        printf("Parent process is exiting.\n");  
        exit(EXIT_SUCCESS);  
    }  
  
    // 等待子进程结束  
    sid = waitpid(-1, NULL, WNOHANG);  
  
    if (sid == -1) {  
        perror("waitpid");  
        exit(EXIT_FAILURE);  
    } else if (sid == 0) {  
        // 子进程还在运行  
        printf("Child process is still running.\n");  
        exit(EXIT_SUCCESS);  
    } else {  
        // 子进程已经结束  
        printf("Child process has finished.\n");  
        exit(EXIT_SUCCESS);  
    }  
}

  • 44
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 42
    评论
评论 42
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

勾栏听曲_0

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

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

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

打赏作者

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

抵扣说明:

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

余额充值