所以我一直在调查如何编写异步代码,我已经提出了以下代码:
我有以下两个问题:
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()
答案 0 :(得分:4)
异步是接口的属性;使用@gen.coroutine
足以使此处理程序异步,因为它会更改界面(返回Future
。除此之外,您不需要在此处使用@asynchronous
装饰器;从Tornado 3.1开始,仅@coroutine
装饰就足够了。此外,由于Motor返回Futures
,我们知道它也是异步的。
阻止是实现的属性;你真正问的是我们如何知道这个处理程序是否是非阻塞的。不幸的是,这是一个棘手的问题。我们从Motor的文档中了解到它的设计和意图是非阻塞,但没有简单的方法可以验证它实际上是完全无阻塞的。有关http://www.tornadoweb.org/en/stable/guide/async.html的异步和非阻塞意味着什么的更多讨论。
Tornado使用单个主线程,因为单线程非阻塞系统可以实现比线程更高的性能(特别是在考虑python GIL施加的限制时),并且使一切异步的复杂性被事实上,您通常不必担心线程安全问题。
答案 1 :(得分:0)
编写异步代码的最佳方法是编写类/函数。 然后调用类/函数。此方法允许事件循环 处理回调。看下面的代码示例,有功能 创建,然后该函数用作回调。这(agian)是 允许Event Loop以异步方式进行回调。
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)