线程BaseHTTPServer,每个请求一个线程

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秒后到达(第一次单击响应).

Mar*_*tke 6

在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方法以在新线程中移动这些东西.