码迷,mamicode.com
首页 > 编程语言 > 详细

Python 源码学习二(SocketServer)

时间:2014-11-14 21:10:10      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:http   io   ar   使用   sp   for   div   on   2014   

SocketServer这个模块中定义的类比较多,但是设计比较清晰,我们以TCPServer为主线分析,先脉络再细节。

总体脉络

将相关类分为两组,如图:

bubuko.com,布布扣

服务器相关(上)

BaseServer是server基础类,定义server的基本处理运行与request处理机制,TCPServer直接继承它。

Request处理类RequestHandler(下)

BaseRequestHandler是request处理的基础类,TCPServer的request处理类StreamRequestHandler直接继承它。

TCPServer设计细节

从类的设计上说,这里可以说时mixin的最佳实践了,什么是mixin?如何使用mixin?

 

A mixin is a special kind of multiple inheritance. There are two main situations where mixins are used:

1 You want to provide a lot of optional features for a class.

2 You want to use oRequestHandlerClassne particular feature in a lot of different classes.

在这些类的设计中始终围绕如何处理socket请求。通常,处理方式三种:

 

synchronous (one request is handled at a time)

forking (each request is handled by a new process)

threading (each request is handled by a new thread)

其中,BaseServer作为基础类,实现服务器的监听以及同步处理方法。初始化参数有两个:server_address和RequestHandlerClassserver_forever方法中使用select方式轮询,是否有客户端连接到服务器。

def serve_forever(self, poll_interval=0.5):
    self.__is_shut_down.clear()
    try:
      while not self.__shutdown_request:
        r, w, e = _eintr_retry(select.select, [self], [], [],poll_interval)
      if self in r:
        self._handle_request_noblock()
    finally:
      self.__shutdown_request = False
      self.__is_shut_down.set()

如果有客户端连接,则使用同步的方式进行处理,最终调用一个RequestHandlerClass类进行处理。

def _handle_request_noblock(self):
     try:
      request, client_address = self.get_request()
     except socket.error:
      return
     if self.verify_request(request, client_address):
       try:
         self.process_request(request, client_address)
       except:
         self.handle_error(request, client_address)
         self.shutdown_request(request)

  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)

其中,TCPServer继承自BaseServer,加入了TCP的一些配置,但是运行机制时完全继承的。所以,此时的TCPServer就是第一种情情况。而多进程和多线程方式则通过mixin设计而成。以多线程的ThreadingTCPServer为例:

class ThreadingMixIn:
  daemon_threads = False
  def process_request_thread(self, request, client_address):
    try:
      self.finish_request(request, client_address)
      self.shutdown_request(request)
    except:
      self.handle_error(request, client_address)
      self.shutdown_request(request)

  def process_request(self, request, client_address):
    t = threading.Thread(target = self.process_request_thread,
               args = (request, client_address))
    t.daemon = self.daemon_threads
    t.start()

在ThreadingMixIn类中,覆写process_request方法,对于每个request都创建一个线程进行处理。此时,多线程的情况只要这样:

class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass

注意,mixin类要放在前面,因为它覆写了TCPServer类的process_request方法。

在SocketServer完美体现了mixin两个设计原则:

ThreadingMixIn这个mixin类作为一个多线程的特性附加在了TCPServer上,同时这个特性又不仅仅是提供给TCPServer使用,还给UDPServer使用。

Python 源码学习二(SocketServer)

标签:http   io   ar   使用   sp   for   div   on   2014   

原文地址:http://www.cnblogs.com/dxm2025/p/4098086.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!