僵尸进程和处理方式

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int main()
{
	int n;
	int i;
	char *s;
	pid_t pid=fork();
	assert(pid!=-1);
        if(pid == 0)
        {
                n=2;
                s="child";
        }
        else
        {
                n=5;
                s="parent";
        }
        for(i=0;i<n;i++)
        {
                printf("%d,%s\n",getpid(),s);
                sleep(1);
        }
       	return 0;
}


在父程序中用于判断子程序是否结束

僵尸进程
子进程提前于父进程结束,造成无法清理掉pcb和其他系统消耗造成pid的长时间占用(如上图)

如果父进程异常结束时就成了一个孤儿进程交个pid=1 的init作为父进程进行管理收尸;

三种处理方式

⒈父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起问题父进程在wait处会阻塞如果父进程很忙会造成一系列

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <assert.h>
int main()
{
	signal(SIGCHLD,fun);
	char *p=NULL;
	pid_t pid=fork();
	assert(pid!=-1);
	int n=0;
	if(pid==0)
	{
			p="child";
			n=10;
	}
	else
	{
		p="parent";
		n=20;
	}
	int i=0;
	for(;i<n;i++)
	{
			printf("%s\n",p);
			sleep(1);
	}
    if(pid!=0)
    {
	wait();
    }
	return 0;
}

⒉ 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler,因为子进程结束后, 父进程会收到该信号,可以在handler中调用wait回收。

第二种代码(只要在父进程收到子进程结束的信号时就去处理该信号)

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <assert.h>
void fun(int sig)
{
		printf("sig=%d\n",sig);
		wait();
		signal(SIGCHLD,SIG_DFL);//回复默认
}
int main()
{
	signal(SIGCHLD,fun);
	char *p=NULL;
	pid_t pid=fork();
	assert(pid!=-1);
	int n=0;
	if(pid==0)
	{
			p="child";
			n=10;
	}
	else
	{
		p="parent";
		n=20;
	}
	int i=0;
	for(;i<n;i++)
	{
			printf("%s\n",p);
			sleep(1);
	}
	return 0;
}

⒊ 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCHLD,SIG_IGN) 通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收, 并不再给父进程发送信号。

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <assert.h>
int main()
{
	signal(SIGCHLD,SIG_IGN);
	char *p=NULL;
	pid_t pid=fork();
	assert(pid!=-1);
	int n=0;
	if(pid==0)
	{
			p="child";
			n=10;
	}
	else
	{
		p="parent";
		n=20;
	}
	int i=0;
	for(;i<n;i++)
	{
			printf("%s\n",p);
			sleep(1);
	}
	return 0;
}


 还就是fork两次,父进程fork一个子进程,然后继续工作,子进程fork一 个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收 还要自己做。相比与第一种的好处就是父进程不用等因为子进程在父进程运行时很快就结束了;
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <assert.h>
int main()
{
	char *p=NULL;
	pid_t pid=fork();
	assert(pid!=-1);
	int n=0;
	if(pid==0)
	{
			pid_t pid=fork();
			if(pid==0)
			{
				p="child";
				n=5;
			}
			else
			{
					printf("%d",getpid());
					exit(0);//使他提前结束孙进程交给pid=1;
			}
	}
	else
	{
		p="parent";
		n=20;
	}
    wait(NULL);
	int i=0;
	for(;i<n;i++)
	{
			printf("pid=%d,%s\n",getpid(),p);
			sleep(1);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Linux 中,僵尸进程和孤儿进程都是指与父进程不再有联系的进程,它们通常是由于进程管理不当或程序错误导致的。 **僵尸进程**是已经完成执行任务,但其父进程还没有来得及处理其退出状态的进程。当进程完成执行后,它的退出状态(也称为退出码或终止状态)会被保存在系统中,直到父进程通过 `wait` 或 `waitpid` 等函数来获取该状态。如果父进程没有处理该状态,那么该进程就会成为僵尸进程,占用系统资源。要清理僵尸进程,可以使用 `kill` 命令向其父进程发送 `SIGCHLD` 信号,或者重新编写程序,使其正确处理子进程的退出状态。 **孤儿进程**是指其父进程已经退出或被终止,但其自身仍在运行的进程。孤儿进程会被 `init` 进程进程号为 `1`)接管,`init` 进程会定期检查系统中是否有孤儿进程,并且将其的父进程设置为 `init` 进程。要避免孤儿进程的产生,可以在父进程退出之前,等待子进程的退出,或者将子进程的父进程设置为 `init` 进程。 可以使用 `ps` 命令来查看系统中的僵尸进程和孤儿进程。使用以下命令可以查看所有僵尸进程: ``` ps aux | grep 'Z' ``` 其中,`aux` 选项用于显示所有进程,`grep 'Z'` 用于查找所有状态为 `Z` 的进程,即僵尸进程。 使用以下命令可以查看所有孤儿进程: ``` ps -ejH ``` 其中,`-e` 选项用于显示所有进程,`-j` 选项用于以层次结构的形式显示进程,`-H` 选项用于显示所有孤儿进程

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值