2

所以我一直在研究如何编写异步代码,我想出了下面的代码:

我有以下两个问题:

  1. 我们怎么能假设这段代码是异步的?我们只是依赖于使用 gen 模块使其异步的事实(当然我们需要为 gen 协程编写异步模块)
  2. 为什么龙卷风会合并一个主线程?我们可以有一个主线程链接到另一个线程池的线程池吗?这个问题更倾向于我们用一个主线程实现什么?
from tornado import gen
import tornado.web
import tornado.ioloop
import motor

class MainHandler(tornado.web.RequestHandler):
  @tornado.web.asynchronous
  @gen.coroutine
  def get(self):
    post = yield db.user.find_one()
    print post
    self.write(post['name'])

handlers=[(
(r'/', MainHandler)
)]

db = motor.MotorClient().example

if __name__ == '__main__':
  application = tornado.web.Application(handlers,debug=True)
  application.listen(8888)
  tornado.ioloop.IOLoop.instance().start()
4

2 回答 2

4

异步性是接口的一个属性;using@gen.coroutine足以使这个处理程序异步,因为它改变了接口(返回一个Future. 顺便说一句,你不需要在@asynchronous这里使用装饰器;因为 Tornado 3.1@coroutine单独装饰器就足够了)。此外,由于 Motor 返回Futures到被让出,我们知道它也是异步的。

阻塞实现的一个属性;你真正要问的是我们如何知道这个处理程序是否是非阻塞的。不幸的是,这是一个更棘手的问题。我们从 Motor 的文档中知道它的设计和意图是非阻塞的,但是没有简单的方法来验证它实际上是完全非阻塞的。在http://www.tornadoweb.org/en/stable/guide/async.html上有更多关于异步和非阻塞意味着什么的讨论。

Tornado 使用单个主线程,因为单线程非阻塞系统可以实现比线程系统更高的性能(特别是考虑到 python GIL 施加的限制时),并且使一切异步的复杂性被您所抵消的事实所抵消通常不需要担心线程安全问题。

于 2015-01-18T18:08:46.080 回答
0

编写异步代码的最佳方式是编写类/函数。然后调用类/函数。此方法允许事件循环处理回调。看下面的代码示例,创建了函数,然后将该函数用作回调。这(agian)允许事件循环以异步方式进行回调。

from tornado.httpclient import AsyncHTTPClient

def asynchronous_fetch(url, callback):
    http_client = AsyncHTTPClient()
    def handle_response(response):
        callback(response.body)
    http_client.fetch(url, callback=handle_response)
于 2015-01-18T19:19:15.607 回答