- 积分
- 16843
在线时间 小时
最后登录1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?开始注册
x
在维护服务器的时候,发现有多个nova-novncproxy的僵尸进程。" b0 T- x! y2 i; B# U6 W. n- H
7 S1 V G/ J- D+ K m26327 ? S 0:05 \_ /usr/bin/python /usr/bin/nova-novncproxy --config-file=/etc/nova/nova.conf, K! }% F9 C' C0 P
4765 ? Z 0:00 \_ [nova-novncproxy] <defunct>& _: Q4 q8 d: o. b" o9 Y2 `/ F
4766 ? Z 0:00 \_ [nova-novncproxy] <defunct>9 L6 T' N2 O, d8 r; z
4767 ? Z 0:00 \_ [nova-novncproxy] <defunct>
9 F" V: z7 Z* I% i. m 4768 ? Z 0:00 \_ [nova-novncproxy] <defunct>" E7 Q8 Q2 y5 h! O Z; U: B7 H5 }2 g
4769 ? Z 0:00 \_ [nova-novncproxy] <defunct>
Y0 v# T9 k: A! z! B之前对于僵尸进程的了解并不深,该如何处理。# u* U3 x5 L6 E2 X( D ^
# P6 b" J3 g) B2 f& y9 h% z定义
( d+ `7 e0 b; w$ T3 Q( \2 E8 y; U% h" I
In UNIX System terminology, a process that has terminated,but whose parent has not yet waited for it, is called a zombie.
/ ~: }7 J% E# u$ a3 g% n( x2 w& {! H6 `0 E/ Q
在UNIX 系统中,一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他, 那么他将变成一个僵尸进程. 在fork()/execve()过程中,假设子进程结束时父进程仍存在,而父进程fork()之前既没安装SIGCHLD信号处理函数调用 waitpid()等待子进程结束,又没有显式忽略该信号,则子进程成为僵尸进程。
+ ^% j r# _- ^8 b3 x5 j" O2 s$ f- H$ c1 } p1 L/ q9 e
如何查看linux系统上的僵尸进程,如何统计有多少僵尸进程?
+ i* l% t0 L/ T6 Q8 c; F
/ x7 [! N+ Q1 M+ ?, C#ps -ef | grep defunct
, O o1 c, `" {7 f1 z0 R5 p0 Q
3 F! O# G1 J$ ~6 n0 c0 [或者查找状态为Z的进程,Z就是代表zombie process,僵尸进程的意思。, g( ]5 Z Y7 B: b1 h6 K( o" D
+ U0 x' T& j; T8 Y3 Q, G另外使用top命令查看时有一栏为S,如果状态为Z说明它就是僵尸进程。
3 m* ]; K: a# ^$ p8 ^ ~
6 a$ f3 t# ^# B' t$ y/ c3 u: oTasks: 95 total, 1 running, 94 sleeping, 0 stopped, 0 zombie Y+ W8 W' r4 D$ n X( Z! H
+ h2 E/ @* W8 [/ P& e8 i& z6 utop命令中也统计了僵尸进程。或者使用下面的命令:
; j2 Q) g6 x$ Y& j* A
. N9 U' `, M; Sps -ef | grep defunct | grep -v grep | wc -l
' r+ W' Q' A1 B" M5 R" {. N6 c& L
9 F) U' Y& e; V8 O& g7 o如何杀死僵尸进程呢?% z. c8 h$ P8 m4 P% l
一般僵尸进程很难直接kill掉,不过您可以kill僵尸爸爸。父进程死后,僵尸进程成为”孤儿进程”,过继给1号进程init,init始终会负责清理僵尸进程.它产生的所有僵尸进程也跟着消失。
1 l5 }* T$ `( P/ Y- P
2 [$ Z" H; U1 `8 U9 u R' i' ?5 Xps -e -o ppid,stat | grep Z | cut -d” ” -f2 | xargs kill -9
3 R7 B: n# d- p! }/ H: X/ n1 M( j; `/ ]4 g
或% a" B( h/ q# X6 n
6 k. d$ E; M" G' u
kill -HUP `ps -A -ostat,ppid | grep -e ’^[Zz]‘ | awk ’{print $2}’`
; U$ V( |' `) l# M, [
/ l9 [0 L" g. _/ Q当然您可以自己编写更好的shell脚本,欢迎与大家分享。
+ f' ^" F0 F. [# @* S( R
( n: V4 \1 o% H我将nova-novncproxy stop后再start,僵尸进程即消失,问题解决。
' L2 P# h* B! @. e; a
/ Y& X; p1 K( i$ c. N另外子进程死后,会发送SIGCHLD信号给父进程,父进程收到此信号后,执行waitpid()函数为子进程收尸。就是基于这样的原理:就算父进程没有调用wait,内核也会向它发送SIGCHLD消息,而此时,尽管对它的默认处理是忽略,如果想响应这个消息,可以设置一个处理函数。1 y/ r6 y* \' c% X1 T
7 x' R1 i$ R: i如何避免僵尸进程呢?% s p) u# c& S5 K6 J+ Q# q
处理SIGCHLD信号并不是必须的。但对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求。如果父进程不等待子进程结束,子进程将成为僵尸进程(zombie)从而占用系统资源。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。在Linux下 可以简单地将 SIGCHLD信号的操作设为SIG_IGN。
m/ g" f6 Q' }( [3 W1 r; Dsignal(SIGCHLD,SIG_IGN);
* u2 _/ a, S0 _* k+ G) W. l# ^5 q这样,内核在子进程结束时不会产生僵尸进程。这一点与BSD4不同,BSD4下必须显式等待子进程结束才能释放僵尸进程
8 v6 d2 x& q1 Q3 S; `# a/ s
/ L, l. i2 N# P- A. }( Y' ^或者5 a5 G6 E& J; x. ~4 u Y' d
# D: k5 A+ \9 K0 n7 t4 K用两次fork(),而且使紧跟的子进程直接退出,是的孙子进程成为孤儿进程,从而init进程将负责清除这个孤儿进程。 |
|