我正在学习异步和Torando以及挣扎。首先,可以在Tornado中使用执行者类吗?
以下示例我正在创建一个websocket,当收到消息时,我想将check()作为后台的另一个进程运行。这是一个人为的例子,仅仅是为了我的学习。 INSIDE或AFTER都没有打印出来。如果我们有这个执行器类,为什么我们需要像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")
答案 0 :(得分:0)
要使用yield
,您必须使用@tornado.gen.coroutine
(或@gen.engine
)。 @tornado.web.asynchronous
与yield
的使用无关,通常仅用于基于回调的处理程序(@asynchronous
仅适用于常规处理程序,而不适用于websockets)。更改装饰器,你应该看到你的打印语句运行。
为什么有人会编写像Motor这样的异步库而不是像这样使用执行程序?为了表现。线程或进程池比异步执行相同的操作要昂贵得多(主要是在内存方面)。当你需要一个没有异步对应的库时,使用执行程序没有错,但如果它可用,那么使用异步版本会更好(如果性能很重要,那么在需要时写一个异步版本。)
另请注意,ProcessPoolExecutor可能很棘手:提交给执行程序的所有参数都必须是可选择的,这对于大型对象来说可能很昂贵。在大多数情况下,我建议使用ThreadPoolExecutor,只需要包装同步库。