tornado版本及多线程情况梳理

来源:互联网 发布:人工智能计算器电脑版 编辑:程序博客网 时间:2024/06/06 03:47
  1.  python2.6  tornado-4.2-py26环境
  2. import tornado.ioloopimport tornado.webfrom tornado.web import asynchronousfrom 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.ioloopimport tornado.webfrom tornado.web import asynchronousfrom concurrent import futures executor = futures.ThreadPoolExecutor(max_workers=2)import timeimport tracebackdef 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)