`
phyeas
  • 浏览: 161061 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

在Python3.0中处理web请求3-多线程

阅读更多

继续研究Python3进行处理web请求。在第一篇文章的Hello World程序中,是没有进行多线程处理的,导致的情况是当第一个人执行了一个操作,如果这个操作所需要的时间比较长,那么其他人就需要等他执行完后才能访问,这是非常不符合逻辑的,我看了下源码,HTTPServer确实没有进行任何线程处理,若运行以下代码:

#!coding=UTF-8
from http.server import HTTPServer,BaseHTTPRequestHandler
import io,shutil,time

class MyHttpHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        print(self.path)
        if self.path=='/':time.sleep(5)
        print(self.path)
        r_str="Hello World";
        enc="UTF-8"
        encoded = ''.join(r_str).encode(enc)
        f = io.BytesIO()
        f.write(encoded)
        f.seek(0)
        self.send_response(200)
        self.send_header("Content-type", "text/html; charset=%s" % enc)
        self.send_header("Content-Length", str(len(encoded)))
        self.end_headers()
        shutil.copyfileobj(f,self.wfile)

httpd=HTTPServer(('',8080),MyHttpHandler)
print("Server started on 127.0.0.1,port 8080.....")
httpd.serve_forever()

 

然后用浏览器分别访问http://localhost:8080/  和http://localhost:8080/?t ,这里先以A页面代表第一个连接,B页面代表第二个连接,如果先访问A页面,则B页面也必须等待A页面完成后(5秒后)才出结果,请求被阻塞了

 

几经努力,在python3的socketserver模块找到了解决办法。其中解决这个问题的一个非常重要的类就是:ThreadingMixIn

看看这个类的__doc__:

"""Mix-in class to handle each request in a new thread."""

 太好了,正是我们要找到,参考官方的例子,得到这个Hello World多线程版代码如下:

#!coding=UTF-8
from http.server import HTTPServer,BaseHTTPRequestHandler
import io,shutil,time,socketserver
class MyThreadingHTTPServer(socketserver.ThreadingMixIn, HTTPServer):
    pass

class MyHttpHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        print(self.path)
        if self.path=='/':time.sleep(5)
        print(self.path)
        r_str="Hello World";
        enc="UTF-8"
        encoded = ''.join(r_str).encode(enc)
        f = io.BytesIO()
        f.write(encoded)
        f.seek(0)
        self.send_response(200)
        self.send_header("Content-type", "text/html; charset=%s" % enc)
        self.send_header("Content-Length", str(len(encoded)))
        self.end_headers()
        shutil.copyfileobj(f,self.wfile)

httpd=MyThreadingHTTPServer(('',8080),MyHttpHandler)
print("Server started on 127.0.0.1,port 8080.....")
httpd.serve_forever()

 只需要很少改动,就能将程序变成多线程了,得益于python的多继承机制。官方的文档和例子:

http://docs.python.org/3.0/library/socketserver.html

 

同时,socketserver里还要一个多进程处理的类:ForkingMixIn,用法和这个一样,只是改下父类名

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics