activeChildren, of the process IDs of all child processes it spawns. Whenever a new
incoming client request is received, the server runs its reapChildren to issue a wait for
any dead children by issuing the standard Python os.waitpid(0,os.WNOHANG) call.
The os.waitpid call attempts to wait for a child process to exit and returns its process
ID and exit status. With a 0 for its first argument, it waits for any child process. With
the WNOHANG p a r a m e t e r f o r i t s s e c o n d , i t d o e s n o t h i n g i f n o c h i l d p r o c e s s h a s e x i t e d ( i. e. ,
it does not block or pause the caller). The net effect is that this call simply asks the
operating system for the process ID of any child that has exited. If any have, the process
ID returned is removed both from the system process table and from this script’s
activeChildren list.
To see why all this complexity is needed, comment out the reapChildren call in this
script, run it on a platform where this is an issue, and then run a few clients. On my
Linux server, a ps -f full process listing command shows that all the dead child pro-
cesses stay in the system process table (show as <defunct>):
[...]$ ps –f
UID PID PPID C STIME TTY TIME CMD
5693094 9990 30778 0 04:34 pts/0 00:00:00 python fork-server.py
5693094 10844 9990 0 04:35 pts/0 00:00:00 [python] <defunct>
5693094 10869 9990 0 04:35 pts/0 00:00:00 [python] <defunct>
5693094 11130 9990 0 04:36 pts/0 00:00:00 [python] <defunct>
5693094 11151 9990 0 04:36 pts/0 00:00:00 [python] <defunct>
5693094 11482 30778 0 04:36 pts/0 00:00:00 ps -f
5693094 30778 30772 0 04:23 pts/0 00:00:00 -bash
When the reapChildren c o m m a n d i s r e a c t i v a t e d , d e a d c h i l d z o m b i e e n t r i e s a r e c l e a n e d
up each time the server gets a new client connection request, by calling the Python
os.waitpid f u n c t i o n. A f e w z o m b i e s m a y a c c u m u l a t e i f t h e s e r v e r i s h e a v i l y l o a d e d , b u t
they will remain only until the next client connection is received (you get only as many
zombies as processes served in parallel since the last accept):
[...]$ python fork-server.py &
[1] 20515
[...]$ ps -f
UID PID PPID C STIME TTY TIME CMD
5693094 20515 30778 0 04:43 pts/0 00:00:00 python fork-server.py
5693094 20777 30778 0 04:43 pts/0 00:00:00 ps -f
5693094 30778 30772 0 04:23 pts/0 00:00:00 -bash
[...]$
Server connected by ('72.236.109.185', 58672) at Sun Apr 25 04:43:51 2010
Server connected by ('72.236.109.185', 58673) at Sun Apr 25 04:43:54 2010
[...]$ ps -f
UID PID PPID C STIME TTY TIME CMD
5693094 20515 30778 0 04:43 pts/0 00:00:00 python fork-server.py
5693094 21339 20515 0 04:43 pts/0 00:00:00 [python] <defunct>
5693094 21398 20515 0 04:43 pts/0 00:00:00 [python] <defunct>
5693094 21573 30778 0 04:44 pts/0 00:00:00 ps -f
5693094 30778 30772 0 04:23 pts/0 00:00:00 -bash
[...]$
Server connected by ('72.236.109.185', 58674) at Sun Apr 25 04:44:07 2010
808 | Chapter 12: Network Scripting
Do
wnload from Wow! eBook <www.wowebook.com>