萧潇墨 2020-02-06 21:41 采纳率: 75%
浏览 723
已结题

python tornado异步接口如何写?

为什么我跟别人写的一样,别人的视频里就有异步效果,而我的还是同步效果
图片说明

代码如下

import tornado.web
import time
import tornado.gen
import tornado.concurrent
from concurrent.futures import ThreadPoolExecutor


class IndexHandler(tornado.web.RequestHandler):
    executor=ThreadPoolExecutor(900)
    @tornado.concurrent.run_on_executor
    def db_querys(self):
        print("开始等待")
        time.sleep(10)
        print("等待结束")
        print("------------------------------------")
        self.write("ok")
    @tornado.gen.coroutine
    def get(self):
        print("开始执行了")
        yield self.db_querys()
        print("执行结束")






  • 写回答

1条回答

  • 编程介的小学生 2020-02-06 21:52
    关注
    1. 异步处理方案

           在处理请求应用上加上@tornado.web.asynchronous和@tornado.gen.engine装饰器,即可实现异步方法配合实现非阻塞请求处理。请求上加了这两个装饰器,@tornado.web.asynchronous装饰器表明该请求不会自动断掉输出流,且需要显式的调用finish方法。此外,asynchronous需要和@tornado.gen.engine搭配使用。

            请求在没有加上装饰器@tornado.web.asynchronous时,get(post)方法结束后,请求会自动断开,但是加上这个装饰器后,get请求可以直接return且保持连接,直到显式的调用finish方法才会关闭输出流。即,在接受到请求后,get(post)方法直接交给别的函数来处理,处理完后再由get(post)方法调用finish()来关闭输出流。

           但是,当异步处理函数里有死循环导致get(post)处理函数阻塞,亦不能让服务器处理别的请求。因为Tornado是单线程事件驱动模式的服务器,一旦方法阻塞,必然导致服务器阻塞。不过,依然有办法处理这种情况,那就是开启多线程。

    1. 异步处理实现

    #-*- coding:utf-8 -*-
    import tornado.httpserver
    import tornado.ioloop
    import tornado.options
    import tornado.web
    import os.path
    import logging
    import time
    from tornado.concurrent import run_on_executor
    from concurrent.futures import ThreadPoolExecutor
    from tornado.options import define, options

    绝对路径

    tool_path = os.path.abspath(os.path.dirname(__file__))

    log config

    logging.basicConfig(level=logging.DEBUG,format="[%(asctime)s] %(levelname)s %(message)s", datefmt="%Y-%m-%d %H:%M:%S")

    #定义端口为8888
    define("port", default=8888, help="run on the given port", type=int)

    POST请求

    class IndexHandler(tornado.web.RequestHandler):
    # 线程池
    max_thread_num = 10
    executor = ThreadPoolExecutor(max_workers=max_thread_num)

    # 线程内处理
    @run_on_executor
    #@tornado.gen.coroutine 支持异步处理
    def my_func(self):
        # do your thing
        time.sleep(10)
        return 1
    
    @tornado.web.asynchronous
    @tornado.gen.engine #同步处理,不能及时响应
    #@tornado.gen.coroutine 支持异步处理
    def post(self):
        res = yield self.my_func()
        self.write(str(res))
        self.finish()
    

    def callback():
    print("start web server process")

    主函数

    def main():
    tornado.options.parse_command_line()
    # 定义app
    app = tornado.web.Application(
    handlers=[(r'/test', IndexHandler)]
    )
    http_server = tornado.httpserver.HTTPServer(app,callback())
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

    if name == '__main__':
    main()

    1. 异步处理验证

    连续发送请求两次,判断下该服务是否异步处理请求。如果是单步处理,则两条请求返回时间应该相差10s。如图所示,两条请求是几乎同时处理完成的,说明异步处理成功。

    评论

报告相同问题?

悬赏问题

  • ¥15 乘性高斯噪声在深度学习网络中的应用
  • ¥15 运筹学排序问题中的在线排序
  • ¥15 关于docker部署flink集成hadoop的yarn,请教个问题 flink启动yarn-session.sh连不上hadoop,这个整了好几天一直不行,求帮忙看一下怎么解决
  • ¥30 求一段fortran代码用IVF编译运行的结果
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集
  • ¥15 C++ 头文件/宏冲突问题解决
  • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
  • ¥50 安卓adb backup备份子用户应用数据失败
  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛
  • ¥30 python代码,帮调试,帮帮忙吧