找回密码
 注册
查看: 4350|回复: 1

如何杀死僵尸进程呢?zombie进程

[复制链接]

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
发表于 2019-6-5 18:11:50 | 显示全部楼层 |阅读模式
在维护服务器的时候,发现有多个nova-novncproxy的僵尸进程。# i6 i( ?& C2 ?2 E
! C9 \1 K8 {3 ^7 k0 I2 j; {2 G
26327 ?        S      0:05  \_ /usr/bin/python /usr/bin/nova-novncproxy --config-file=/etc/nova/nova.conf; F& O5 t( o. x# w$ s& _# m" p( t+ ^
4765 ?        Z      0:00      \_ [nova-novncproxy] <defunct>3 L4 z2 {4 e& G# f3 C/ k
4766 ?        Z      0:00      \_ [nova-novncproxy] <defunct>3 D6 L+ S1 `* M/ S% x
4767 ?        Z      0:00      \_ [nova-novncproxy] <defunct>1 T6 W% j; V3 C' |! ]
4768 ?        Z      0:00      \_ [nova-novncproxy] <defunct>
1 Z: i% I4 ?9 ^ 4769 ?        Z      0:00      \_ [nova-novncproxy] <defunct>4 J& ?' \0 W$ k- t) O7 u0 t$ P
之前对于僵尸进程的了解并不深,该如何处理。. I; T' u6 \5 M' J
4 \6 k1 l6 m% A7 g& z, P
定义4 }3 g' w" W1 ?) }: T' Z/ j
: p5 z( k8 W% d  C
In UNIX System terminology, a process that has terminated,but whose parent has not yet waited for it, is called a zombie./ z3 H5 X1 e$ |# S  W

) F3 O# K6 c* c$ K1 a' [% @2 ^& z     在UNIX 系统中,一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他, 那么他将变成一个僵尸进程.  在fork()/execve()过程中,假设子进程结束时父进程仍存在,而父进程fork()之前既没安装SIGCHLD信号处理函数调用 waitpid()等待子进程结束,又没有显式忽略该信号,则子进程成为僵尸进程。; l5 u9 o4 _; Z7 j

' i. f3 w' `, L1 U  D$ `9 j如何查看linux系统上的僵尸进程,如何统计有多少僵尸进程?; V5 t2 B. |+ y( [/ T

$ w8 G7 c) o7 p7 X#ps -ef | grep defunct" s; _0 `$ m6 K" n/ S. _

# V, x3 a3 t: i0 H' _7 n或者查找状态为Z的进程,Z就是代表zombie process,僵尸进程的意思。0 \' @; `5 ~% g; a; |% ^
2 Y% w, U5 V% p# ?' `; L
另外使用top命令查看时有一栏为S,如果状态为Z说明它就是僵尸进程。9 u+ E+ Y% J0 @5 v: T* H5 j( A9 C- M. s

) Y6 y' X, O) a. _* GTasks:  95 total,   1 running,  94 sleeping,   0 stopped,   0 zombie
  B' @8 u6 P) Z8 g  b. X2 l) l3 @
: x6 g. E; L+ N4 ]$ ftop命令中也统计了僵尸进程。或者使用下面的命令:
3 e1 U$ v4 _4 y9 z( ?4 X
! T9 B2 o, `" L+ M7 l" X9 Z) Sps -ef | grep defunct | grep -v grep | wc -l
5 C+ x( ^1 a  P
( t$ P2 O$ g: y' P6 R) `6 C如何杀死僵尸进程呢?
' I% T2 i$ z+ w7 ^7 V; Q( j一般僵尸进程很难直接kill掉,不过您可以kill僵尸爸爸。父进程死后,僵尸进程成为”孤儿进程”,过继给1号进程init,init始终会负责清理僵尸进程.它产生的所有僵尸进程也跟着消失。
+ ]# r. ?7 B9 `# V$ C# @& C
9 a0 ^% L1 M( Xps -e -o ppid,stat | grep Z | cut -d” ” -f2 | xargs kill -9+ W8 A& c! [" X1 \

* ?; l& q- d' G4 t3 y7 j0 \) ]  N  @0 a: O+ d
3 T, _2 C  B" `4 |
kill -HUP `ps -A -ostat,ppid | grep -e ’^[Zz]‘ | awk ’{print $2}’`
! w' d4 W/ c( O3 w* Q+ R$ W3 k  E
当然您可以自己编写更好的shell脚本,欢迎与大家分享。! x1 K: }3 q& P2 l& b

& ~" m2 @! b4 u3 B我将nova-novncproxy stop后再start,僵尸进程即消失,问题解决。
3 S( R; L/ m- _/ e# d0 }3 O
) [- u+ F- F1 n另外子进程死后,会发送SIGCHLD信号给父进程,父进程收到此信号后,执行waitpid()函数为子进程收尸。就是基于这样的原理:就算父进程没有调用wait,内核也会向它发送SIGCHLD消息,而此时,尽管对它的默认处理是忽略,如果想响应这个消息,可以设置一个处理函数。* O% ?+ O! S2 N
( ^8 G4 s9 }1 ^/ ^/ ]/ g) P$ y
如何避免僵尸进程呢?
7 G: v; z4 q8 B$ P! c8 c$ C1 q' y处理SIGCHLD信号并不是必须的。但对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求。如果父进程不等待子进程结束,子进程将成为僵尸进程(zombie)从而占用系统资源。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。在Linux下 可以简单地将 SIGCHLD信号的操作设为SIG_IGN。2 m0 J  U5 Y# y& r, d0 Z
signal(SIGCHLD,SIG_IGN);% I  o- i! l4 Y5 K" W6 i
这样,内核在子进程结束时不会产生僵尸进程。这一点与BSD4不同,BSD4下必须显式等待子进程结束才能释放僵尸进程
6 s  B6 ~( i0 S0 T
4 @# _' c0 h6 Z9 q6 R) L1 X或者! x6 k* e; l/ M

2 S$ h( G" x. Y" Z9 Y用两次fork(),而且使紧跟的子进程直接退出,是的孙子进程成为孤儿进程,从而init进程将负责清除这个孤儿进程。

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
 楼主| 发表于 2020-6-2 13:59:28 | 显示全部楼层
ps -e -o ppid,stat | grep Z | cut -d " " -f2 | xargs kill -9   直接杀死僵尸进程。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

返回首页|Archiver|手机版|小黑屋|易陆发现技术论坛 ( 蜀ICP备2026014127号-1 )

GMT+8, 2026-6-12 03:24 , Processed in 0.018627 second(s), 22 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表