tornado版本及多线程情况梳理

  1.  python2.6  tornado-4.2-py26环境
  2. import tornado.ioloop
    import tornado.web
    from tornado.web import asynchronous
    from concurrent import futures 
    executor = futures.ThreadPoolExecutor(max_workers=2)
    
    def call(handler):
        handler.write("Hello, World!")
        handler.finish() # 如果不写这行则回挂住
    
    class MainHandler(tornado.web.RequestHandler):
        
        @asynchronous
        def get(self):
            executor.submit(call, self)
    
    def make_app():
        return tornado.web.Application([
            (r"/", MainHandler),
        ])  
    
    if __name__ == "__main__":
        app = make_app()
        app.listen(9090)
        tornado.ioloop.IOLoop.current().start()
    ~                                             

    如果get/post返回future/gen(异步, yield的生成器), 则需申明asynchronous, 不然该future不会加入IOLoop的事件, 直接处理完成, 如果在线程/协程中再有finish调用, 则会出现finish() called twice, 下面会详细说到。反过来说如果申明是asynchronous, 必需返回future 或者 gen 
  3. finish() call twice 示例代码:需注意线程抛的异常,主线程是catch不到的
  4. import tornado.ioloop
    import tornado.web
    from tornado.web import asynchronous
    from concurrent import futures 
    executor = futures.ThreadPoolExecutor(max_workers=2)
    import time
    import traceback
    
    def call(handler):
        try:
             print id(handler)
             handler.write("Hello, World! id: %s" % id(handler))
             time.sleep(5)
             handler.finish()
             print "over.id[%s]" % id(handler)
        except:
            print traceback.format_exc()
    
    class MainHandler(tornado.web.RequestHandler):
        
        #@asynchronous
        def get(self):
            executor.submit(call, self)
    
    def make_app():
        return tornado.web.Application([
            (r"/", MainHandler),
        ])  
    
    if __name__ == "__main__":
        app = make_app()
        app.listen(9090)
        tornado.ioloop.IOLoop.current().start()
  5. 另外注意如果使用tornado.ioloop.IOLoop.instance().add_callback(lambda: handler.finish({"xx": "yy"}))  返回值最好是字符串, 编码如果出现问题,则用户不会调用到finish,源码如下:
  6.     def write(self, chunk):
            
            if self._finished:
                raise RuntimeError("Cannot write() after finish()")
            if not isinstance(chunk, (bytes, unicode_type, dict)):
                message = "write() only accepts bytes, unicode, and dict objects"
                if isinstance(chunk, list):
                    message += ". Lists not accepted for security reasons; see http://www.tornadoweb.org/en/stable/web.html#tornado.web.RequestHandler.write"
                raise TypeError(message)
            if isinstance(chunk, dict):
                chunk = escape.json_encode(chunk)  # 这里会报 'utf8' codec can't decode bytes
                self.set_header("Content-Type", "application/json; charset=UTF-8")
            chunk = utf8(chunk)
            self._write_buffer.append(chunk)



你可能感兴趣的:(python)