【问题标题】:Why asynchronous function in tornado is blocking?为什么龙卷风中的异步函数会阻塞?
【发布时间】:2014-02-07 12:25:44
【问题描述】:

为什么传入的请求没有被处理,而另一个请求处于“等待”状态?

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

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

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

我使用 tornado 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()

【问题讨论】:

    标签: python python-2.7 asynchronous tornado yield


    【解决方案1】:

    实际上,对“localhost:8080/”的每个新请求都会导致您的应用程序打印“incoming call”。但是,对“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 的现代“协程”界面而不是 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()
    

    【讨论】:

    • 我提到它的目的是永远不会完成请求。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多