Tornado中異步框架的使用


tornado的同步框架與其他web框架相同都是處理先來的請求,如果先來的請求阻塞,那么后面的請求也會處理不了。一直處於等待過程中。但是請求一旦得到響應,那么:

  • 請求發送過來后,將需要的本站資源直接返回給客戶端
  • 請求發送過來后,本站沒有需要的資源,從其它站點獲取過來,再返回給客戶端

一、Tornado中的同步框架

1、本站資源直接返回

import tornado.web
import time
 
class LoginHandler(tornado.web.RequestHandler):
 
    def get(self):
        time.sleep(10) #第一個請求來后等10s,后面的請求無法處理,只有等這個請求結束后才能處理其他的請求
        self.write('LoginHandler')
 
    def post(self):
        pass
 
class IndexHandler(tornado.web.RequestHandler):
 
    def get(self):
        self.write('IndexHandler')
 
    def post(self):
        pass
 
application=tornado.web.Application([
    (r'/login/',LoginHandler),
    (r'/index/', IndexHandler),
 
],)
 
if __name__ == '__main__':
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

可以看到因為回調函數中阻塞了10s,所以后面的請求必須等這個回調函數結束后才能處理后面的請求,在tornado中使用future對象進行異步處理。

2、從其它站點獲取資源再返回

import tornado.web
import requests
 
class LoginHandler(tornado.web.RequestHandler):
 
    def get(self):
        requests.get('http://www.baidu.com') #此時無法處理其它請求
        self.write('LoginHandler')
 
    def post(self):
        pass
 
class IndexHandler(tornado.web.RequestHandler):
 
    def get(self):
        self.write('IndexHandler')
 
    def post(self):
        pass
 
application=tornado.web.Application([
    (r'/login/',LoginHandler),
    (r'/index/', IndexHandler),
 
],)
 
if __name__ == '__main__':
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

從其它站點獲取資源的過程也是阻塞的,服務端處理不了其它請求,必須等這個請求處理完畢才能處理其它請求。

二、Tornado中的異步框架

對於上面的兩種情況tornado也是有對策的,就是使用future對象,進行異步處理。

1、本站資源直接返回

import tornado.web
from tornado import gen
from tornado.concurrent import Future
import time
 
class LoginHandler(tornado.web.RequestHandler):
    @gen.coroutine
    def get(self):
        future=Future()
        tornado.ioloop.IOLoop.current().add_timeout(time.time()+10,self.done) #此處的10s延遲不會影響處理其它請求
        yield future
 
    def done(self,*args,**kwargs):
        self.write('LoginHandler')
        self.finish()
 
    def post(self):
        pass
 
class IndexHandler(tornado.web.RequestHandler):
 
    def get(self):
        self.write('IndexHandler')
 
    def post(self):
        pass
 
application=tornado.web.Application([
    (r'/login/',LoginHandler),
    (r'/index/', IndexHandler),
 
],)
 
if __name__ == '__main__':
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

2、從其它站點獲取資源再返回

import tornado.web
from tornado import gen
from tornado import httpclient
 
class LoginHandler(tornado.web.RequestHandler):
 
    @gen.coroutine
    def get(self):
        http=httpclient.AsyncHTTPClient()
        yield http.fetch('http://www.google.com',self.done) #訪問其它網址不能用requests,應該使用tornado內置的,其實質也是返回future對象
 
    def done(self,*args,**kwargs):
 
        self.write('LoginHandler')
        self.finish()
 
 
    def post(self):
        pass
 
class IndexHandler(tornado.web.RequestHandler):
 
    def get(self):
        self.write('IndexHandler')
 
    def post(self):
        pass
 
application=tornado.web.Application([
    (r'/login/',LoginHandler),
    (r'/index/', IndexHandler),
 
],)
 
if __name__ == '__main__':
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

  tornado解決異步請求就是利用future對象。future對象中設定默認參數result=None,如果在某一時刻future的result中被設定值了,那么它就會自動執行回調函數,實際上這種執行回調函數的功能就是所謂的異步,不需要服務器等待,自己自動執行完后會進行回調(注意這都是在一個線程中)。詳情參考:https://www.cnblogs.com/shenjianping/p/11622210.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM