ivi*_*ica 3 python multithreading
我正在尝试使用BaseHttpServer和创建一个多线程Web服务器ThreadingMixIn(如各种示例所示).伪代码类似于:
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
pass
def do_POST(self):
pass
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
"""Handle requests in a separate thread."""
if __name__ == '__main__':
server = ThreadedHTTPServer(('localhost', 9999), Handler)
print 'Starting server, use <Ctrl-C> to stop'
server.serve_forever()
Run Code Online (Sandbox Code Playgroud)
这可以按预期工作,但我的问题是并非每个请求都获得一个线程,但是每个URL都进行了线程化.我测试过这样:我有一个URL绑定执行以下方法:
import time
import datetime
def request_with_pause(self):
print datetime.datetime.now().strftime("%H:%M:%S.%f"), 'REQUEST RECEIVED'
time.sleep(10)
print datetime.datetime.now().strftime("%H:%M:%S.%f"), 'SENT RESPONSE'
Run Code Online (Sandbox Code Playgroud)
它运行正常,除非我在5秒暂停时调用url 两次(单击URL,等待5秒并再次单击它) - 两个"响应"在10秒后到达(第一次单击响应).
在Python 2.7中:
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from threading import Thread
class ThreadedHTTPServer(HTTPServer):
def process_request(self, request, client_address):
thread = Thread(target=self.__new_request, args=(self.RequestHandlerClass, request, client_address, self))
thread.start()
def __new_request(self, handlerClass, request, address, server):
handlerClass(request, address, server)
self.shutdown_request(request)
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write("hello world")
server = ThreadedHTTPServer(('', 80), Handler)
#server.serve_forever()
Run Code Online (Sandbox Code Playgroud)
您可以在SocketServer.py中找到HTTPServer类的主要源代码,您可以在Python目录的Lib文件夹中找到它.(HTTPServer继承自TCPServer,TCPServer继承自BaseServer.)
重要的是315:
def process_request(self, request, client_address):
self.finish_request(request, client_address)
self.shutdown_request(request)
def finish_request(self, request, client_address):
self.RequestHandlerClass(request, client_address, self)
Run Code Online (Sandbox Code Playgroud)
此时,服务器使用您的Handler类创建新的请求对象.所述BaseRequestHandler构造自动调用self.setup(),self.handle()和self.finish()方法.
所以我所做的是覆盖process_request方法以在新线程中移动这些东西.