如何将 python tornado @gen.coroutine 与 long 运行 函数一起使用
How to use python tornado @gen.coroutine with long running functions
我有一个网络应用程序也在进行非常密集的数据处理。
有些功能非常慢(想想几分钟)。
直到现在,我的体系结构都会为每个连接生成新的 threads/process,因此那些缓慢的功能不会阻止其他用户。但这会消耗太多内存,并且不符合 Tornado 架构。
所以我想知道是否有解决此类问题的方法。
我的代码如下所示:
# code that is using to much memory because of the new threads being spawned
def handler():
thread = Thread(target = really_slow_function)
thread.start()
thread.join()
return "done"
def really_slow_function():
# this is an example of an intensive function
# which should be treated as a blackbox
sleep(100)
return "done"
重构后我有以下代码:
#code that doesn't scale because all the requests are block on that one slow request.
@gen.coroutine
def handler():
yield really_slow_function()
raise gen.Return("done")
def really_slow_function():
# this is an example of an intensive function
# which should be treated as a blackbox
sleep(100)
return "done"
此重构的问题是 Tornado 服务器在 really_slow_function
上阻塞并且无法同时处理其他请求。
所以问题是:有没有一种方法可以在不触及 really_slow_function
并且不创建新的 threads/process 的情况下重构处理程序?
在单独的线程中使用 ThreadPoolExecutor
(来自 concurrent.futures
包)到 运行 long-运行ning 函数,而不是每次都启动一个新线程。
async def handler():
await IOLoop.current().run_in_executor(None, really_slow_function)
return "done"
如果你想精确控制有多少线程有资格运行这个函数,你可以创建自己的执行器并传递它而不是None
。
我有一个网络应用程序也在进行非常密集的数据处理。 有些功能非常慢(想想几分钟)。
直到现在,我的体系结构都会为每个连接生成新的 threads/process,因此那些缓慢的功能不会阻止其他用户。但这会消耗太多内存,并且不符合 Tornado 架构。
所以我想知道是否有解决此类问题的方法。 我的代码如下所示:
# code that is using to much memory because of the new threads being spawned
def handler():
thread = Thread(target = really_slow_function)
thread.start()
thread.join()
return "done"
def really_slow_function():
# this is an example of an intensive function
# which should be treated as a blackbox
sleep(100)
return "done"
重构后我有以下代码:
#code that doesn't scale because all the requests are block on that one slow request.
@gen.coroutine
def handler():
yield really_slow_function()
raise gen.Return("done")
def really_slow_function():
# this is an example of an intensive function
# which should be treated as a blackbox
sleep(100)
return "done"
此重构的问题是 Tornado 服务器在 really_slow_function
上阻塞并且无法同时处理其他请求。
所以问题是:有没有一种方法可以在不触及 really_slow_function
并且不创建新的 threads/process 的情况下重构处理程序?
在单独的线程中使用 ThreadPoolExecutor
(来自 concurrent.futures
包)到 运行 long-运行ning 函数,而不是每次都启动一个新线程。
async def handler():
await IOLoop.current().run_in_executor(None, really_slow_function)
return "done"
如果你想精确控制有多少线程有资格运行这个函数,你可以创建自己的执行器并传递它而不是None
。