| # | |
| # Example where a pool of http servers share a single listening socket | |
| # | |
| # On Windows this module depends on the ability to pickle a socket | |
| # object so that the worker processes can inherit a copy of the server | |
| # object. (We import `multiprocessing.reduction` to enable this pickling.) | |
| # | |
| # Not sure if we should synchronize access to `socket.accept()` method by | |
| # using a process-shared lock -- does not seem to be necessary. | |
| # | |
| # Copyright (c) 2006-2008, R Oudkerk | |
| # All rights reserved. | |
| # | |
| import os | |
| import sys | |
| from multiprocessing import Process, current_process, freeze_support | |
| from BaseHTTPServer import HTTPServer | |
| from SimpleHTTPServer import SimpleHTTPRequestHandler | |
| if sys.platform == 'win32': | |
| import multiprocessing.reduction # make sockets pickable/inheritable | |
| def note(format, *args): | |
| sys.stderr.write('[%s]\t%s\n' % (current_process().name, format%args)) | |
| class RequestHandler(SimpleHTTPRequestHandler): | |
| # we override log_message() to show which process is handling the request | |
| def log_message(self, format, *args): | |
| note(format, *args) | |
| def serve_forever(server): | |
| note('starting server') | |
| try: | |
| server.serve_forever() | |
| except KeyboardInterrupt: | |
| pass | |
| def runpool(address, number_of_processes): | |
| # create a single server object -- children will each inherit a copy | |
| server = HTTPServer(address, RequestHandler) | |
| # create child processes to act as workers | |
| for i in range(number_of_processes-1): | |
| Process(target=serve_forever, args=(server,)).start() | |
| # main process also acts as a worker | |
| serve_forever(server) | |
| def test(): | |
| DIR = os.path.join(os.path.dirname(__file__), '..') | |
| ADDRESS = ('localhost', 8000) | |
| NUMBER_OF_PROCESSES = 4 | |
| print 'Serving at http://%s:%d using %d worker processes' % \ | |
| (ADDRESS[0], ADDRESS[1], NUMBER_OF_PROCESSES) | |
| print 'To exit press Ctrl-' + ['C', 'Break'][sys.platform=='win32'] | |
| os.chdir(DIR) | |
| runpool(ADDRESS, NUMBER_OF_PROCESSES) | |
| if __name__ == '__main__': | |
| freeze_support() | |
| test() |