如何删除僵尸进程

转载~~

今天在维护服务器的时候,发现有5个nova-novncproxy的僵尸进程。

26327 ? S 0:05 _ /usr/bin/python /usr/bin/nova-novncproxy –config-file=/etc/nova/nova.conf
4765 ? Z 0:00 _ [nova-novncproxy]
4766 ? Z 0:00 _ [nova-novncproxy]
4767 ? Z 0:00 _ [nova-novncproxy]
4768 ? Z 0:00 _ [nova-novncproxy]
4769 ? Z 0:00 _ [nova-novncproxy]
之前对于僵尸进程的了解并不深,赶紧找了篇相关文章来学习一下,该如何处理。

定义

In UNIX System terminology, a process that has terminated,but whose parent has not yet waited for it, is called a zombie.

 在UNIX 系统中,一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他, 那么他将变成一个僵尸进程.  在fork()/execve()过程中,假设子进程结束时父进程仍存在,而父进程fork()之前既没安装SIGCHLD信号处理函数调用 waitpid()等待子进程结束,又没有显式忽略该信号,则子进程成为僵尸进程。

如何查看linux系统上的僵尸进程,如何统计有多少僵尸进程?

ps -ef | grep defunct

或者查找状态为Z的进程,Z就是代表zombie process,僵尸进程的意思。

另外使用top命令查看时有一栏为S,如果状态为Z说明它就是僵尸进程。

Tasks: 95 total, 1 running, 94 sleeping, 0 stopped, 0 zombie

top命令中也统计了僵尸进程。或者使用下面的命令:

ps -ef | grep defunct | grep -v grep | wc -l

如何杀死僵尸进程呢?
一般僵尸进程很难直接kill掉,不过您可以kill僵尸爸爸。父进程死后,僵尸进程成为”孤儿进程”,过继给1号进程init,init始终会负责清理僵尸进程.它产生的所有僵尸进程也跟着消失。

ps -e -o ppid,stat | grep Z | cut -d” ” -f2 | xargs kill -9

kill -HUP ps -A -ostat,ppid | grep -e ’^[Zz]‘ | awk ’{print $2}’

当然您可以自己编写更好的shell脚本,欢迎与大家分享。

我将nova-novncproxy stop后再start,僵尸进程即消失,问题解决。

另外子进程死后,会发送SIGCHLD信号给父进程,父进程收到此信号后,执行waitpid()函数为子进程收尸。就是基于这样的原理:就算父进程没有调用wait,内核也会向它发送SIGCHLD消息,而此时,尽管对它的默认处理是忽略,如果想响应这个消息,可以设置一个处理函数。

如何避免僵尸进程呢?
处理SIGCHLD信号并不是必须的。但对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求。如果父进程不等待子进程结束,子进程将成为僵尸进程(zombie)从而占用系统资源。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。在Linux下 可以简单地将 SIGCHLD信号的操作设为SIG_IGN。
signal(SIGCHLD,SIG_IGN);
这样,内核在子进程结束时不会产生僵尸进程。这一点与BSD4不同,BSD4下必须显式等待子进程结束才能释放僵尸进程

或者

用两次fork(),而且使紧跟的子进程直接退出,是的孙子进程成为孤儿进程,从而init进程将负责清除这个孤儿进程。

None

perl 如何关闭僵尸进程

05-15

我想实现一个多进程的功能,从文件夹中读取pl脚本,每个执行一个脚本对于一个进程,进程数最多只能同时运行4个rn如果多于四个,其他进程就等待有进程结束被回收后才能运行新的进程,但是我下面的代码无法回收运行完成的进程,请大家帮忙看一下,哪里出问题了?如何进行回收僵尸进程?谢谢!rn为了便于测试,我脚本把执行pl脚本的child函数注释掉了,用sleep 代替,不影响演示进程回收的效果。rn[code=Perl]rn#! /perl/bin/perlrnuse POSIX ":sys_wait_h";rnrn#$SIGCHLD = "IGNORE";rn# 活动进程数rnmy $num_pro = 0;rn# 回收的进程数rnmy $num_collect = 0;rnmy $collect;rnrn## == 控制进程数量,子进程每发送一次退出信号,活动进程就减一 ==rn$SIGCHLD = sub $num_pro--;rnrnmy $home = "d:\\etl\\process";rnopendir DH, $home or die "无法打开目录\n $!";rnprint "打开目录\n";rnrnsub childrn my $file = @_[0];rn $file =~ s/.pl//i;rn print "进程$file, 执行中...\n";rn sleep 4;rn if ($file == 'process2') rn sleep 16;rn rnrnrnsub mainrn my $i = 0;rn foreach $file (grep(/.pl$/i, readdir DH)) rn next if $file =~ /^\./;rn next if (-d "$home\\$file");rn my $pid = fork();rn $i ++;rn if(!defined($pid))rn print "创建异常\n";rn exit 1;rn rn if($pid == 0)rn print "进程开始$$\n";rn #&child($file);rn sleep 5;rn print "进程结束$$\n";rn exit 0;rn rn # 每创建一个进程,活动进程数量加1rn $num_pro ++;rn print "活动进程数: $num_pro\n";rn if(($i - $num_pro - $num_collect) > 0)rn while(($collect = waitpid(-1, WNOHANG)) > 0)rn print $collect . "状态\n";rn $num_collect ++;rn rn rn rn while($num_pro > 3)rn print "等待...回收:$num_collect\n";rn sleep(2);rn rn rn closedir DH;rnrnrnmain();rn[/code]

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试