我正在尝试使用Tornado的gen.coroutine
函数进行简单的异步调用。这是我目前的代码:
from tornado import gen
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
@gen.coroutine
def get(self):
q = self.get_argument('query')
print q
response = yield self.process(q)
self.write(response)
@gen.coroutine
def process(self, query):
# just a long loop
for i in range(int(query)*100):
for j in range(i):
a = 10*10*10*10*10*10
return {'processed': True}
def make_app():
return tornado.web.Application([
(r"/search", MainHandler),
])
if __name__ == "__main__":
app = make_app()
port = 8888
print "listening on port: ", port
app.listen(port)
tornado.ioloop.IOLoop.current().start()
但是,它不是以异步方式运行。我在这做错了什么?
答案 0 :(得分:3)
您的"流程"方法只进行计算,所以它永远不会为Tornado的事件循环提供在其他任务上工作的机会,同时处理"在跑。 Tornado可以交错并发网络操作,但是它不能并行运行Python代码。并行化像你的"过程"方法需要多个Python子进程。
答案 1 :(得分:3)
您的函数阻止事件循环,在process()
函数完成或将控制权重新放回事件循环之前,不能处理任何其他任务。对于这种情况,您可以简单地使用yield None
(以前是yield gen.moment
)来休息,让事件循环运行其他任务然后恢复处理。例如:
@gen.coroutine
def process(self, query):
for i in range(int(query)*100):
for j in range(i):
a = 10*10*10*10*10*10
if j % 500 == 0:
yield None # yield the inner loop
if i % 500 == 0:
yield None # yield outer loop
return {'processed': True}
希望这可以帮助您实现所需的并发级别。
http://www.tornadoweb.org/en/stable/gen.html#tornado.gen.moment