searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Linux避免僵尸进程两种方式

2023-11-17 01:11:34
13
0

一、什么是僵尸进程

子进程退出时,父进程并未对其发出的SIGCHLD信号进行适当处理,导致子进程停留在僵死状态等待其父进程为其收尸,这个状态下的子进程就是僵死进程。

僵尸进程将会占据系统资源,由于系统的进程ID是有限的,所以大量的僵尸进程会导致用户创建进程失败。

二、避免僵尸进程两种方式

方式1

父进程可以马上退出,使得子进程成为孤儿进程,由系统将子进程的ppid改为1(init进程),并由init进程来回收子进程的资源。

实现这一要求的技巧是fork两次。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
 
int main()
{
    pid_t pid;
    if((pid = fork())<0){
        printf("fork err\n");
        exit(0);
    }else if(pid == 0){
        if((pid = fork())<0){
            printf("fork err\n");
            exit(0);
        }else if(pid > 0){
            //第一次fork的子进程退出,此时第二次fork的子进程还在活动(sleep),
            //退出后第二次fork的子进程将成为孤儿进程
            exit(0);
        }
        sleep(2);
        printf("second child,parent pid = %d\n",getppid());
        exit(0);
    }
    //父进程等待第一次fork的子进程退出,由于子进程调用了exit(0),所以可以很快回收子进程资源并退出
    if(waitpid(pid,NULL,0)!= pid){ 
        printf("waitpid error\n");
        exit(0);
    }
    exit(0);
}

方式2

父进程声明一个信号处理函数,得到子进程的退出信号,然后在信号处理函数调用wait函数彻底结束子进程。

#include<signal.h>
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/wait.h>
 
pid_t pid;     
 
void handle_child(int sig)
{
	//得到子进程的退出信号后调用wait函数释放子进程资源
    if(waitpid(pid,NULL,0)!=pid){
        printf("waitpid error\n");
        exit(0);
    }
    printf("child exit\n");
   exit(0);
}
                
int main()
{ 
    (void) signal (SIGCHLD,handle_child);
    if((pid = fork())<0){
        printf("fork error\n");
        exit(0);
    }
    if(pid == 0){
        //子进程睡眠2秒后退出
        sleep(2);
        exit(0);
    }
    while(1)
    {
        sleep(1);
    }
}
0条评论
0 / 1000
x****n
4文章数
1粉丝数
x****n
4 文章 | 1 粉丝
原创

Linux避免僵尸进程两种方式

2023-11-17 01:11:34
13
0

一、什么是僵尸进程

子进程退出时,父进程并未对其发出的SIGCHLD信号进行适当处理,导致子进程停留在僵死状态等待其父进程为其收尸,这个状态下的子进程就是僵死进程。

僵尸进程将会占据系统资源,由于系统的进程ID是有限的,所以大量的僵尸进程会导致用户创建进程失败。

二、避免僵尸进程两种方式

方式1

父进程可以马上退出,使得子进程成为孤儿进程,由系统将子进程的ppid改为1(init进程),并由init进程来回收子进程的资源。

实现这一要求的技巧是fork两次。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
 
int main()
{
    pid_t pid;
    if((pid = fork())<0){
        printf("fork err\n");
        exit(0);
    }else if(pid == 0){
        if((pid = fork())<0){
            printf("fork err\n");
            exit(0);
        }else if(pid > 0){
            //第一次fork的子进程退出,此时第二次fork的子进程还在活动(sleep),
            //退出后第二次fork的子进程将成为孤儿进程
            exit(0);
        }
        sleep(2);
        printf("second child,parent pid = %d\n",getppid());
        exit(0);
    }
    //父进程等待第一次fork的子进程退出,由于子进程调用了exit(0),所以可以很快回收子进程资源并退出
    if(waitpid(pid,NULL,0)!= pid){ 
        printf("waitpid error\n");
        exit(0);
    }
    exit(0);
}

方式2

父进程声明一个信号处理函数,得到子进程的退出信号,然后在信号处理函数调用wait函数彻底结束子进程。

#include<signal.h>
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/wait.h>
 
pid_t pid;     
 
void handle_child(int sig)
{
	//得到子进程的退出信号后调用wait函数释放子进程资源
    if(waitpid(pid,NULL,0)!=pid){
        printf("waitpid error\n");
        exit(0);
    }
    printf("child exit\n");
   exit(0);
}
                
int main()
{ 
    (void) signal (SIGCHLD,handle_child);
    if((pid = fork())<0){
        printf("fork error\n");
        exit(0);
    }
    if(pid == 0){
        //子进程睡眠2秒后退出
        sleep(2);
        exit(0);
    }
    while(1)
    {
        sleep(1);
    }
}
文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
1
1