Linux 高并发学习笔记 - wait 函数回收子进程,信号回收子进程,解决僵尸进程

文章介绍了Linux系统中孤儿进程和僵尸进程的概念,强调了父进程回收子进程内核区数据的重要性。wait和waitpid函数用于处理子进程状态变化,而SIGCHLD信号可用于即时回收子进程,防止僵尸进程占用资源。
摘要由CSDN通过智能技术生成
2.2.5 回收子进程

Linux 高并发学习笔记 - 笔记索引

孤儿进程与僵尸进程
  • 孤儿进程父进程结束、子进程尚未结束,此时子进程孤儿进程,其父进程归为init进程PID1)。孤儿进程虽然脱离父进程控制,但是会自然结束,通常不具有危害。
  • 僵尸进程子进程结束、父进程尚未结束,如果父进程未处理子进程的结束信息,未回收子进程的内核区数据,此时子进程僵尸进程。在进程概述中讲到,子进程结束不会自动释放内核区数据,等待父进程接收并处理其结束信息。如果处于将死状态的子进程一直存在,将不断占用内核区内存和PID,大量积累具有危害。
  • 父进程不处理僵尸进程,在其结束后,init进程会为其处理僵尸进程。但是如果父进程是长期运行的进程(如服务器进程),危害将持续积累。
  • wait函数与waitpid函数用于处理和回收子进程内核区数据。
wait 函数回收子进程
  • wait函数与waitpid函数用于接收进程状态变化,默认阻塞进程等待任意子进程状态变化。

  • 返回值:当任意进程状态变化,函数返回子进程PID,设置wstatus值表示该子进程状态变化编码(后述情况不设置wstatus);当WNOHANG选项打开,并且存在未结束子进程,返回0;当所有子进程已回收,抛出No child process错误,返回-1;当出现其他错误,返回-1

  • pid:分为下述情况:

    • < -1:等待任意组ID-pidpid的绝对值)的子进程状态变化。
    • -1:等待任意子进程状态变化。
    • 0:等待任意组ID与函数启动时父进程组ID相同的子进程状态变化。
    • > 0:等待进程IDpid子进程状态变化。
    • 如果对应进程符号ID要求但不是子进程子孙进程不属于子进程)的,不属于控制范围。
  • wstatus:整型指针,用于接收状态变化编码,可为NULL表示不接收信息。解码宏如下:

    • WIFEXITED(wstatus):返回01整型。是否正常退出(exit为正常退出)。
    • WEXITSTATUS(wstatus):返回整型。如果上宏为真,返回退出状态(exit参数,0~255)。
    • WIFSIGNALED(wstatus):返回01整型。是否异常退出(信号退出为异常退出)。
    • WTERMSIG(wstatus):返回整型。如果上宏为真,返回引发退出的信号。
    • WIFSTOPPED(wstatus):返回01整型。是否进入暂停。
    • WSTOPSIG(wstatus):返回整型。如果上宏为真,返回引发暂停的信号。
    • WIFCONTINUED(wstatus):返回01整型。是否进程继续。
  • options:宏如下:(使用|连接)

    • (默认):等待进程正常退出、进程异常退出(与被追踪进程暂停)。
    • WNOHANG:不阻塞,立即返回。
    • WUNTRACED:等待进程(未被追踪进程)被暂停。
    • WCONTINUED:等待进程被继续。
  • wait(wstatus)等价于waitpid(-1, wstatus, 0)

  • 关于更多:$ man 2 wait

#include <sys/types.h>
#include <sys/wait.h>
// wait for the change state
pid_t wait(int *wstatus);
pid_t waitpid(pid_t pid, int *wstatus, int options);

#include <stdio.h>
// print error message if return value is -1
perror("wait");
信号回收子进程
  • 我们注意到wait函数回收子进程时,需要主动检测是否有子进程状态变化;如果我们希望即使处理子进程,必须阻塞的回收子进程,或者使用独立线程处理子进程。在2.3.4 信号章节中将提到,子进程状态变化时将触发SIGCHLD信号,届时可以考虑使用信号即时回收子进程。
// 请先了解 2.3.4 信号 章节后阅读此代码
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
void process_signal(int sig) {
    if (sig == SIGCHLD) {
        int ret = 1, wstatus;
        while (ret > 0) {
            waitpid(-1, &wstatus, WNOHANG);
            // 业务逻辑
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值