[英]Explaining python tornado async
因此,我一直在研究如何編寫異步代碼,並且提出了以下代碼:
我有以下兩個問題:
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()
異步性是接口的屬性; 使用@gen.coroutine
足以使此處理程序異步,因為它會更改接口(以返回Future
。 @asynchronous
,您無需在此處使用@asynchronous
裝飾器;由於Tornado 3.1以來,僅@coroutine
裝飾器就可以了。足夠)。 此外,由於Motor返回了要產生的Futures
,因此我們知道它也是異步的。
阻塞是執行的財產; 您真正要問的是我們如何知道此處理程序是否是非阻塞的。 不幸的是,這是一個棘手的問題。 從Motor的文檔中我們知道它的設計和意圖是無阻塞的,但是沒有簡單的方法來驗證它實際上是完全無阻塞的。 在http://www.tornadoweb.org/en/stable/guide/async.html上有更多關於異步和非阻塞意味着什么的討論。
Tornado使用一個主線程是因為單線程非阻塞系統比線程系統可以獲得更高的性能(尤其是在考慮python GIL施加的限制時),並且使所有內容異步的復雜性被以下事實抵消了:通常不需要擔心線程安全性問題。
編寫異步代碼的最佳方法是編寫類/函數。 然后調用類/函數。 此方法允許事件循環處理回調。 看下面的代碼示例,創建了一個函數,然后將該函數用作回調。 這(允許)使事件循環以異步方式執行回調。
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.