1# 2# Example where a pool of http servers share a single listening socket 3# 4# On Windows this module depends on the ability to pickle a socket 5# object so that the worker processes can inherit a copy of the server 6# object. (We import `processing.reduction` to enable this pickling.) 7# 8# Not sure if we should synchronize access to `socket.accept()` method by 9# using a process-shared lock -- does not seem to be necessary. 10# 11 12import os 13import sys 14 15from multiprocess import Process, current_process as currentProcess, freeze_support as freezeSupport 16from BaseHTTPServer import HTTPServer 17from SimpleHTTPServer import SimpleHTTPRequestHandler 18 19if sys.platform == 'win32': 20 import multiprocess.reduction # make sockets pickable/inheritable 21 22 23def note(format, *args): 24 sys.stderr.write('[%s]\t%s\n' % (currentProcess()._name, format%args)) 25 26 27class RequestHandler(SimpleHTTPRequestHandler): 28 # we override log_message() to show which process is handling the request 29 def log_message(self, format, *args): 30 note(format, *args) 31 32def serve_forever(server): 33 note('starting server') 34 try: 35 server.serve_forever() 36 except KeyboardInterrupt: 37 pass 38 39 40def runpool(address, number_of_processes): 41 # create a single server object -- children will each inherit a copy 42 server = HTTPServer(address, RequestHandler) 43 44 # create child processes to act as workers 45 for i in range(number_of_processes-1): 46 Process(target=serve_forever, args=(server,)).start() 47 48 # main process also acts as a worker 49 serve_forever(server) 50 51 52def test(): 53 DIR = os.path.join(os.path.dirname(__file__), '..') 54 ADDRESS = ('localhost', 8000) 55 NUMBER_OF_PROCESSES = 4 56 57 print 'Serving at http://%s:%d using %d worker processes' % \ 58 (ADDRESS[0], ADDRESS[1], NUMBER_OF_PROCESSES) 59 print 'To exit press Ctrl-' + ['C', 'Break'][sys.platform=='win32'] 60 61 os.chdir(DIR) 62 runpool(ADDRESS, NUMBER_OF_PROCESSES) 63 64 65if __name__ == '__main__': 66 freezeSupport() 67 test() 68