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 `multiprocessing.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# Copyright (c) 2006-2008, R Oudkerk 12# All rights reserved. 13# 14 15import os 16import sys 17 18from multiprocessing import Process, current_process, freeze_support 19from BaseHTTPServer import HTTPServer 20from SimpleHTTPServer import SimpleHTTPRequestHandler 21 22if sys.platform == 'win32': 23 import multiprocessing.reduction # make sockets pickable/inheritable 24 25 26def note(format, *args): 27 sys.stderr.write('[%s]\t%s\n' % (current_process().name, format%args)) 28 29 30class RequestHandler(SimpleHTTPRequestHandler): 31 # we override log_message() to show which process is handling the request 32 def log_message(self, format, *args): 33 note(format, *args) 34 35def serve_forever(server): 36 note('starting server') 37 try: 38 server.serve_forever() 39 except KeyboardInterrupt: 40 pass 41 42 43def runpool(address, number_of_processes): 44 # create a single server object -- children will each inherit a copy 45 server = HTTPServer(address, RequestHandler) 46 47 # create child processes to act as workers 48 for i in range(number_of_processes-1): 49 Process(target=serve_forever, args=(server,)).start() 50 51 # main process also acts as a worker 52 serve_forever(server) 53 54 55def test(): 56 DIR = os.path.join(os.path.dirname(__file__), '..') 57 ADDRESS = ('localhost', 8000) 58 NUMBER_OF_PROCESSES = 4 59 60 print 'Serving at http://%s:%d using %d worker processes' % \ 61 (ADDRESS[0], ADDRESS[1], NUMBER_OF_PROCESSES) 62 print 'To exit press Ctrl-' + ['C', 'Break'][sys.platform=='win32'] 63 64 os.chdir(DIR) 65 runpool(ADDRESS, NUMBER_OF_PROCESSES) 66 67 68if __name__ == '__main__': 69 freeze_support() 70 test() 71