僵尸进程的形成和处理方法

1. 概念

僵尸进程是由于子进程死了,但是父进程没管,导致子进程的task_struct不释放,内核栈也无法释放,造成资源浪费。进程状态为Z。
在这里插入图片描述
僵尸进程没有释放的资源有:

在Linux系统中,僵尸进程在内核中没有释放的资源主要有以下两个:
内存资源:当子进程结束时,它会释放自己占用的内存资源。但是,如果没有父进程来回收僵尸进程,那么这些进程的状态信息就会一直保存在内核中,占据了一定的内存空间。
文件描述符资源:在Linux系统中,每个进程都有自己的文件描述符表,用于管理该进程打开的文件。当子进程结束时,它的文件描述符表应该被关闭,但是如果没有父进程来回收僵尸进程,那么这些进程的文件描述符表就会一直存在于内核中,占据了一定的文件描述符资源。

2. 解决方案

用sigchild信号解决僵尸进程的产生,通知父进程回收。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
void sys_err(char *str)
{
    perror(str);
    exit(1);
 }
 void do_sig_child(int signo)                    //信号处理函数
 {
    int status;
    pid_t pid;
    while ((pid = waitpid(0, &status, WNOHANG)) > 0) {//判断子进程状态
        if (WIFEXITED(status))
            printf("child %d exit %d\n", pid, WEXITSTATUS(status));
        else if (WIFSIGNALED(status))
            printf("child %d cancel signal %d\n", pid, WTERMSIG(status));
    }   
 }
 int main(void)
 {
     pid_t pid;
     int i;
     for (i = 0; i < 5; i++) {                    //子进程创建
         if ((pid = fork()) == 0)
             break;
         else if (pid < 0)                        //容错处理
             sys_err("fork");
     }
     if (pid == 0) {                                //子进程分支
         int n = 1;
         while (n--) {
             printf("child ID %d\n", getpid());
         }
         exit(i+1);
     }
     else if (pid > 0) {                            //父进程分支
         struct sigaction act;
         act.sa_handler = do_sig_child;
         sigemptyset(&act.sa_mask);
         act.sa_flags = 0;
         sigaction(SIGCHLD, &act, NULL);
         while (1) {
             printf("Parent ID %d\n", getpid());
             sleep(2);
         }
     }
     return 0;
 }

do_sig_child信号处理函数中可以while循环来处理收到的子进程退出信息。由于信号是没有消息队列的,所以如果有信号叠加的话会丢子进程退出信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值