如何在tornado中以异步的方式调用同步函数

问题
如何在tornado的coroutine中调用同步阻塞的函数

解决方案
使用python内置标准库的concurrent.futures.ThreadPoolExecutor和tornado.concurrent.run_on_executor

解决示例
a.使用concurrent.futures.ThreadPoolExecutor

#-*-coding:utf-8-*-
import time
from tornado.gen import coroutine
from tornado.ioloop import IOLoop
from concurrent.futures import ThreadPoolExecutor

def func():
    time.sleep(2)
    print(10)


def foo():
    time.sleep(1)
    print(15)

@coroutine
def main():
    pool = ThreadPoolExecutor(2)
    @coroutine
    def sync_func1():
        yield pool.submit(func,)

    @coroutine
    def sync_func2():
    yield pool.submit(foo,)
t1 = time.time()
yield [sync_func1(), sync_func2()]
print(time.time() - t1)


if __name__ == '__main__':
    IOLoop.current().run_sync(main)

 




b.使用run_on_executor

#-*-coding:utf-8-*-
import os.path
import time
from tornado.gen import coroutine
from tornado.ioloop import IOLoop
from tornado.concurrent import run_on_executor
from concurrent.futures import ThreadPoolExecutor

class My(object):
    def __init__(self):
        self.executor = ThreadPoolExecutor(3)

    @run_on_executor
     def f(self):
        print(os.path.join(os.path.dirname(__file__), 'python'))
        time.sleep(2)
        print(10)

    @run_on_executor 
    def f1(self):
        time.sleep(1)
        print(15)

    @run_on_executor 
    def f2(self):
        time.sleep(1.5)
        print('hello, world!')

@coroutine
def main():
    m = My()
    t1 = time.time()
    yield [m.f1(), m.f2(), m.f()]
    print(time.time() - t1)


if __name__ == '__main__':
    IOLoop.current().run_sync(main)        

 


总结
我们直接运行上面的两个同步的函数,耗时需要3秒。但我们利用了ThreadPoolExecutor之后,总耗时只需要2秒左右。下面是运行结果:

---------------------
作者:Easy_to_python
来源:CSDN
原文:https://blog.csdn.net/hjhmpl123/article/details/53673108
版权声明:本文为博主原创文章,转载请附上博文链接!

posted @ 2019-01-03 14:13  b02330224  阅读(515)  评论(0编辑  收藏  举报