[Python编程(第4版)].(Programming.Python.4th.Edition).Mark.Lutz.文字版

(yzsuai) #1
5693094 11592 30778 0 05:00 pts/0 00:00:00 python signal-demo.py 17
5693094 11728 30778 0 05:01 pts/0 00:00:00 ps -f
5693094 30778 30772 0 04:23 pts/0 00:00:00 -bash

[...]$ kill −17 11592
Got signal 17 at Sun Apr 25 05:01:28 2010
sigchld caught

[...]$ kill −17 11592
Got signal 17 at Sun Apr 25 05:01:35 2010
sigchld caught

[...]$ kill −9 11592
[1]+ Killed python signal-demo.py 17

Now, to apply all of this signal knowledge to killing zombies, simply set the SIGCHLD
signal handler to the SIG_IGN ignore handler action; on systems where this assignment
is supported, child processes will be cleaned up when they exit. The forking server
variant shown in Example 12-6 uses this trick to manage its children.


Example 12-6. PP4E\Internet\Sockets\fork-server-signal.py


"""
Same as fork-server.py, but use the Python signal module to avoid keeping
child zombie processes after they terminate, instead of an explicit reaper
loop before each new connection; SIG_IGN means ignore, and may not work with
SIG_CHLD child exit signal on all platforms; see Linux documentation for more
about the restartability of a socket.accept call interrupted with a signal;
"""


import os, time, sys, signal, signal
from socket import * # get socket constructor and constants
myHost = '' # server machine, '' means local host
myPort = 50007 # listen on a non-reserved port number


sockobj = socket(AF_INET, SOCK_STREAM) # make a TCP socket object
sockobj.bind((myHost, myPort)) # bind it to server port number
sockobj.listen(5) # up to 5 pending connects
signal.signal(signal.SIGCHLD, signal.SIG_IGN) # avoid child zombie processes


def now(): # time on server machine
return time.ctime(time.time())


def handleClient(connection): # child process replies, exits
time.sleep(5) # simulate a blocking activity
while True: # read, write a client socket
data = connection.recv(1024)
if not data: break
reply = 'Echo=>%s at %s' % (data, now())
connection.send(reply.encode())
connection.close()
os._exit(0)


def dispatcher(): # listen until process killed
while True: # wait for next connection,


Handling Multiple Clients | 811
Free download pdf