简体   繁体   English

解释python龙卷风异步

[英]Explaining python tornado async

So I have been investigating into how to write async code, and i have come up with the code below: 因此,我一直在研究如何编写异步代码,并且提出了以下代码:

I have the following two questions: 我有以下两个问题:

  1. How can we assume this code is async? 我们如何才能假定此代码是异步的? We are just meant to rely on the fact that using the gen module makes it async( of course we need to write async modules for the gen coroutine) 我们只是要依靠使用gen模块使其异步的事实(当然,我们需要为gen coroutine编写异步模块)
  2. Why does tornado incorporate one main thread? 龙卷风为什么要合并一个主线程? can we have a main thread linking to a pool of thread which links to another pool of threads? 我们可以有一个主线程链接到一个线程池,而该线程池又链接到另一个线程池吗? This question is more towards what do we achieve with one main thread? 这个问题更多的是关于我们通过一个主线程可以实现什么?
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()

Asynchronousness is a property of the interface ; 异步性接口的属性; using @gen.coroutine is sufficient to make this handler asynchronous because it changes the interface (to return a Future . As an aside, you don't need to use the @asynchronous decorator here; since Tornado 3.1 the @coroutine decorator alone has been enough). 使用@gen.coroutine足以使此处理程序异步,因为它会更改接口(以返回Future@asynchronous ,您无需在此处使用@asynchronous装饰器;由于Tornado 3.1以来,仅@coroutine装饰器就可以了。足够)。 Furthermore, since Motor returns Futures to be yielded, we know that it is also asynchronous. 此外,由于Motor返回了要产生的Futures ,因此我们知道它也是异步的。

Blocking is a property of the implementation ; 阻塞执行的财产; what you're really asking is how we know whether this handler is non-blocking. 您真正要问的是我们如何知道此处理程序是否是非阻塞的。 This, unfortunately is a trickier question. 不幸的是,这是一个棘手的问题。 We know from Motor's documentation that it is designed and intended to be non-blocking, but there is no simple way to verify that it is in fact fully non-blocking. 从Motor的文档中我们知道它的设计和意图是无阻塞的,但是没有简单的方法来验证它实际上是完全无阻塞的。 There is more discussion of what it means to be asynchronous and non-blocking at http://www.tornadoweb.org/en/stable/guide/async.html . http://www.tornadoweb.org/en/stable/guide/async.html上有更多关于异步和非阻塞意味着什么的讨论。

Tornado uses a single main thread because a single-threaded non-blocking system can achieve higher performance than a threaded one (especially when considering the limitations imposed by the python GIL), and the complexity of making everything asynchronous is offset by the fact that you don't generally need to worry about thread-safety issues. Tornado使用一个主线程是因为单线程非阻塞系统比线程系统可以获得更高的性能(尤其是在考虑python GIL施加的限制时),并且使所有内容异步的复杂性被以下事实抵消了:通常不需要担心线程安全性问题。

The best way to write async code is to write classes/functions. 编写异步代码的最佳方法是编写类/函数。 Then call the class/function. 然后调用类/函数。 This method allows the event loop to handle the callback. 此方法允许事件循环处理回调。 Look at code sample below, there is function created, and then the function is used as callback. 看下面的代码示例,创建了一个函数,然后将该函数用作回调。 This (agian) is allowing the Event Loop do a callback in async way. 这(允许)使事件循环以异步方式执行回调。

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM