Python HTTP服务器与多线程
我尝试用Python和线程来创建一个HTTP服务器:
from socketserver import ThreadingMixIn
from http.server import HTTPServer, BaseHTTPRequestHandler
import time, threading
class ThreadingServer(ThreadingMixIn, HTTPServer):
pass
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
print("do")
time.sleep(10)
message = threading.currentThread().getName()
self.wfile.write(message)
self.wfile.write('\n')
if __name__ == "__main__":
httpd = ThreadingServer( (host, port), Handler)
httpd.serve_forever()
这个服务器运行得不错,但如果有两个请求同时到达,它们会一个接一个地执行。也就是说,第二个请求要等第一个请求完成后才能执行。
4 个回答
0
我遇到了同样的问题,发现了一个比较旧的问题。结果发现,对我来说,问题出在我使用了谷歌浏览器。这个浏览器似乎会把对同一个网址的请求排队处理。所以第二个请求在第一个请求的响应还没回来之前是不会发送的,这样就让人觉得服务器是一个一个地处理请求。用 curl -i <你的网址在这里>
就好用多了。
0
Python的设计中有一个叫做全局解释器锁(GIL)的东西,它的作用是确保在任何时候只运行一条Python指令。这就意味着Python不能同时运行多段代码,这也就是为什么你的代码是一个接一个地执行的原因。你可以在这里了解更多关于GIL的信息。
如果你想绕过GIL,有一个选项可以选择:可以看看multiprocessing这个包。
0
你的代码在Python中写得很适合多线程。我看不出有什么理由让它变成顺序执行。你可以试试随机的休眠时间。
顺便说一下:Python中的线程和操作系统的线程不一样。普通的Python脚本是在一个单进程、单线程的虚拟机中运行的,因此在任何时候只能有一个Python线程在运行。(如果你想了解更多,可以查一下GIL)
你可以试试使用PyPy来实现真正的多线程。
1
你说得完全正确:ThreadingMixIn
会让你的整个处理程序变得顺序执行,也就是说它一次只能处理一个请求。
相反,你需要的是这样的东西:
import time, socket, threading
sock = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port = 8000
sock.bind((host, port))
sock.listen(1)
HTTP = "HTTP/1.1 200 OK\nContent-Type: text/html; charset=UTF-8\n\n"
class Listener(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.daemon = True # stop Python from biting ctrl-C
self.start()
def run(self):
conn, addr = sock.accept()
conn.send(HTTP)
# serve up an infinite stream
i = 0
while True:
conn.send("%i " % i)
time.sleep(0.1)
i += 1
[Listener() for i in range(100)]
time.sleep(9e9)
你甚至可以使用上面的方法,而不需要自己写一个HTTP服务器: