为什么龙卷风中的异步功能会阻塞?

时间:2014-02-07 12:25:44

标签: python python-2.7 asynchronous tornado yield

为什么在另一个请求处于“等待”状态时未处理传入请求?

如果查看下面的代码,函数“get”有一个龙卷风任务,该任务使用“yield”关键字执行,这意味着“等待回调执行”。在我的代码中,回调永远不会执行。如果您第二次运行请求,则在第一次处于保持状态时,不会处理第二个请求。如果你运行任何其他请求,它们正在被处理得很好。

所以,我的行动: 1.开始申请 2. GET localhost:8080 /     - 应用程序正在打印输出“来电” 3.获取localhost:8080 / anotherrequest     - 应用程序打印输出“另一个请求” 4. GET localhost:8080 /     - 应用程序不打印任何输出,而我期望它打印“来电”。为什么呢?

那么,为什么这段代码会被阻塞?代码示例已附上。

我使用龙卷风2.1和python 2.7来运行此示例。

谢谢

import tornado
import tornado.web
from tornado import gen

class AnotherHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    def get(self):
        print 'another request'
        self.finish()

class MainHandler(tornado.web.RequestHandler):
    def printStuff(*args, **kwargs):
        print 'incoming call'

    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self):
        result = yield tornado.gen.Task(self.printStuff); 

application = tornado.web.Application([
    (r"/", MainHandler),
    (r"/anotherrequest", AnotherHandler)
])

if __name__ == "__main__":
    application.listen(8080)
    tornado.ioloop.IOLoop.instance().start()

2 个答案:

答案 0 :(得分:2)

对“localhost:8080 /”的每个新请求实际上都会导致您的应用程序打印“来电”。但是,对“localhost:8080 /”的请求永远不会完成。为了使用yield语句,printStuff必须接受回调并执行它。此外,异步get函数必须调用self.finish

class MainHandler(tornado.web.RequestHandler):
    def printStuff(self, callback):
        print 'incoming call'
        callback()

    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self):
        result = yield tornado.gen.Task(self.printStuff)
        self.finish()

使用Tornado的现代“coroutine”界面而不是gen.Task和gen.engine更容易:

class MainHandler(tornado.web.RequestHandler):
    @gen.coroutine
    def printStuff(self):
        print 'incoming call'

    @gen.coroutine
    def get(self):
        result = yield self.printStuff()
        self.finish()

答案 1 :(得分:0)

发现问题,它实际上是在从浏览器发出请求时发生的。随着“卷曲”,一切都按预期工作。对造成的不便表示歉意。