Lea*_*don 3 python asynchronous tornado
我有一个需要一段时间才能运行的函数,需要在请求中运行它.处理此问题的最佳方法是什么,以便此请求在处理时不会阻塞主线程?我看了@tornado.web.asynchronous装饰器,但是当函数不是异步龙卷风模块时,这并没有多大用处.
class LongHandler(tornado.web.RequestHandler):
def get(self):
self.write(self.long_time_function())
def long_time_function(self):
time.sleep(5)
return "foo"
Run Code Online (Sandbox Code Playgroud)
当你有一些阻塞任务不能与异步事件循环一起使用时,你必须把它放在一个单独的线程中.
如果您将拥有无限数量的阻塞任务,则需要使用线程池.
无论哪种方式,您都希望有一个包装器异步任务阻止来自线程任务的通知.
最简单的方法是使用像tornado-threadpool这样的预建库.*然后,你只需要这样做:
class LongHandler(tornado.web.RequestHandler):
@thread_pool.in_thread_pool
def long_time_function(self, callback):
time.sleep(5)
callback("foo")
Run Code Online (Sandbox Code Playgroud)
如果你想自己做,这个要点展示了你必须做的事情的一个例子 - 或者,当然,各种Tornado线程池库的源代码可以作为示例代码.
请记住Python GIL的局限性:如果你的后台任务是CPU限制的(并且在Python中完成了大部分工作,而不是在像Numpy那样释放GIL的C扩展中),那么你必须把它放在一个分开的过程.快速搜索Tornado进程池库并没有找到很多不错的选项,但在Python中调整线程池代码来处理池代码通常非常容易.**
*请注意,我并不是特别推荐该图书馆; 这只是Google搜索中出现的第一件事,从快速浏览看起来它看起来既实用又正确.
**这往往如更换简单concurrent.futures.ThreadPoolExecutor用concurrent.futures.ProcessPoolExecutor或multiprocessing.dummy.Pool用multiprocessing.Pool.唯一的技巧是确保所有的任务参数和返回值都很小并且可以选择.
| 归档时间: |
|
| 查看次数: |
2109 次 |
| 最近记录: |