|
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 |
|
12 import os |
|
13 import sys |
|
14 |
|
15 from multiprocessing import Process, current_process, freeze_support |
|
16 from BaseHTTPServer import HTTPServer |
|
17 from SimpleHTTPServer import SimpleHTTPRequestHandler |
|
18 |
|
19 if sys.platform == 'win32': |
|
20 import multiprocessing.reduction # make sockets pickable/inheritable |
|
21 |
|
22 |
|
23 def note(format, *args): |
|
24 sys.stderr.write('[%s]\t%s\n' % (current_process().name, format%args)) |
|
25 |
|
26 |
|
27 class 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 |
|
32 def serve_forever(server): |
|
33 note('starting server') |
|
34 try: |
|
35 server.serve_forever() |
|
36 except KeyboardInterrupt: |
|
37 pass |
|
38 |
|
39 |
|
40 def 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 |
|
52 def 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 |
|
65 if __name__ == '__main__': |
|
66 freeze_support() |
|
67 test() |