zoukankan      html  css  js  c++  java
  • 如何在tornado中以异步的方式调用同步函数

    tornado相较于flask入门难,精通更难,用两种框架都写一个最简单的带有time.sleep的入门dome就会发现区别,同时进来多个请求flask就不会阻塞(虽然也是单进程但flask会使用selet复用或者多线程方式避免给请求阻塞的感觉),而torndao就会发生阻塞(单进程单线程,一个一个来处理),这样的问题在入门tornado时是需要搞清楚的,一般就是通过 @tornado.web.asynchronous,@tornado.gen.coroutine来解决。

    # -*- coding:utf-8 -*-
    #!/bin/env python
    import os
    import time
    import tornado.httpserver
    import tornado.ioloop
    import tornado.options
    import tornado.web
    import tornado.gen
    import tornado.httpclient
    import tornado.concurrent
    import tornado.ioloop
    from tornado.concurrent import run_on_executor
    from concurrent.futures import ThreadPoolExecutor
    from tornado.options import define, options
    import sys
    
    reload(sys)
    sys.setdefaultencoding('utf8')
    
    """
    https://blog.csdn.net/chenyulancn/article/details/45888949 参考并拓展
    https://blog.csdn.net/hjhmpl123/article/details/53673108
    
    curl http://localhost:8000/sleep
    curl http://localhost:8000/justnow
    
    有2个url,一个是耗时的请求,一个是可以或者说需要立刻返回的请求,希望访问耗时的请求不会影响也不会被其他人的请求
    专业点讲就是:如何在tornado中以异步的方式调用同步函数?
    
    """
    
    
    define("port", default=8000, help="run on the given port", type=int)
    
    class My(object):
        def __init__(self):
            self.executor = ThreadPoolExecutor(2)   #不可以设为1或0
    
        @run_on_executor
        def f(self):
            print(os.path.join(os.path.dirname(__file__), 'python'))
            time.sleep(2)
            print(10)
            return 1,2,3
    
        @run_on_executor
        def f1(self):
            time.sleep(1)
            print(15)
            return 4,5,6    #不要 yield 4,5,6
    
        @run_on_executor
        def f2(self):
            time.sleep(1.5)
            print('hello, world1')
            f11=self.f1()
            f12=self.f()
            a,b,c= f11.result()
            d,e,f= f12.result()
            # a,b,c= yield self.f1()    # 这样是不可以的
            # d,e,f= yield self.f()
            print "a,b,c:",a,b,c
            print "d,e,f:",d,e,f
            print('hello, world2')
            return 'success',a+b+c+d+e+f    #不要 yield 'success',a+b+c+d+e+f
    
    class SleepHandler(tornado.web.RequestHandler):
        @tornado.web.asynchronous
        @tornado.gen.coroutine
        def get(self):
            #yield tornado.gen.Task(tornado.ioloop.IOLoop.instance().add_timeout, time.time() + 5)
            m = My()
            result, m = yield tornado.gen.maybe_future(m.f2())
            yield self.write({"result":result, "sum":m})
    
    
    class JustNowHandler(tornado.web.RequestHandler):
        def get(self):
            self.write("i hope just now see you")
    
    
    if __name__ == "__main__":
        tornado.options.parse_command_line()
        app = tornado.web.Application(handlers=[
            (r"/sleep", SleepHandler), (r"/justnow", JustNowHandler)])
        http_server = tornado.httpserver.HTTPServer(app)
        http_server.listen(options.port)
        tornado.ioloop.IOLoop.instance().start()
    
  • 相关阅读:
    eclipse 构建 jpa project 所需的用户库(vendor: EclipseLink)
    <mvc:resources mapping="/xxx/**" location="/xxx/"/>无效,可能和Controller的URL模式有关
    面向对象设计的基本原则
    MySql数据库时区异常,java.sql.SQLException: The server time zone value '?й???׼ʱ?' is unrecognized or represents more than one time zone.
    elasticsearch kibana + 分词器安装详细步骤
    neo4j企业版集群搭建
    Elasticsearchdump 数据导入/导出
    Hive环境搭建和SparkSql整合
    Hadoop 集群搭建和维护文档
    HBase 安装snappy压缩软件以及相关编码配置
  • 原文地址:https://www.cnblogs.com/lgjbky/p/9377210.html
Copyright © 2011-2022 走看看