Asynchronous 龙卷风和并发的。期货。执行者

Asynchronous 龙卷风和并发的。期货。执行者,asynchronous,tornado,future,Asynchronous,Tornado,Future,我正在学习async和Torando,并且正在努力学习。首先,在Tornado中是否可以使用executor类 下面的示例中,我正在创建一个websocket,当收到一条消息时,我希望在后台以另一个进程的形式运行check()。这是一个人为的例子,只是为了我的学习。里面和后面都不会被打印出来。如果我们有这个executor类,为什么我们需要异步特定的包,比如Motor 另外,在我所看到的Torando的所有示例中,@gen.coroutine总是在扩展tornado.web.RequestHan

我正在学习async和Torando,并且正在努力学习。首先,在Tornado中是否可以使用executor类

下面的示例中,我正在创建一个websocket,当收到一条消息时,我希望在后台以另一个进程的形式运行check()。这是一个人为的例子,只是为了我的学习。里面和后面都不会被打印出来。如果我们有这个executor类,为什么我们需要异步特定的包,比如Motor

另外,在我所看到的Torando的所有示例中,@gen.coroutine总是在扩展tornado.web.RequestHandler的类上完成。在我的示例中,我使用的是tornado.websocket.WebSocketHandler@gen.coroutine也可以在这个类中使用吗

最后,有人能推荐一本关于这个主题的书或深入的教程吗?我买了《龙卷风简介》,但它有点过时,因为它使用了tornado.gen.engine

def check(msg):

   time.sleep(10)
   return msg

class SessionHandler(tornado.websocket.WebSocketHandler):
   def open(self):
      pass

   def on_close(self):
      pass


   # not sure if i needed this decorator or not? 
   @tornado.web.asynchronous
   def on_message(self,message):
      print("INSIDE")

      with concurrent.futures.ProcessPoolExecutor() as executor:
          f=executor.submit(check,"a")
          result = yield f
      print("AFTER")

为了使用
产量
,您必须使用
@tornado.gen.coroutine
(或
@gen.engine
@tornado.web.asynchronous
yield
的使用无关,通常仅与基于回调的处理程序一起使用(
@asynchronous
仅在常规处理程序中有效,而不在WebSocket中有效)。更改decorator,您将看到打印语句正在运行

为什么有人要编写一个异步库,比如Motor,而不是使用这样的执行器?为了表现。线程或进程池的成本(主要是内存方面)要比异步执行相同的操作高得多。当您需要一个没有异步副本的库时,使用executor没有错,但是如果异步版本可用,最好使用异步版本(如果性能足够重要,在需要异步版本时编写异步版本)


还要注意,ProcessPoolExecutor可能很棘手:提交给executor的所有参数都必须是可拾取的,这对于大型对象来说可能会很昂贵。在大多数情况下,如果您只想包装一个同步库,我建议使用ThreadPoolExecutor。

非常感谢您提供了内容丰富的答案。我注意到,许多不使用回调的示例也使用@asynchronous进行装饰。你是说这没必要吗?再次感谢你,这在当前版本的《龙卷风》中是不必要的;我认为在Tornado的一些早期3.x版本中,有必要同时使用
@asynchronous
@gen.coroutine
,但现在建议单独使用
@gen.coroutine