日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

tornado 第一篇

發布時間:2023/12/9 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 tornado 第一篇 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?一:異步和非阻塞IO

  實時的web特性通常需要每個用戶一個大部分時間,在傳統的同步web服務器中,這意味著需要給每個用戶分配一個專用的線程,這樣的開銷是十分巨大

  tornado使用啦一種單線程事件循環的方式,這意味著所有的應用代碼都應該是異步和非阻塞的,因為在同一時刻只有一個操作是有效的

  1,阻塞

    一個函數在等到返回值等都是阻塞的,

    一個函數可以在某些方面阻塞而在其他方面不阻塞,舉例說明。tornado,httpclient在默認設置下講阻塞與DNS解析,但是在其他網絡請求時不會阻塞(為了減輕這種影響,可以用ThreadeResolver 或通過正確配置libcurl使用tornado.curl_htpclient),在Tornado的上下文中我們通常討論網絡I/O上下文阻塞,雖然各種阻塞已經被最小化啦

  2,異步

    一個異步函數在在它結束前就已經返回啦,而且通常會在程序中觸發一些動作然后在后頭執行一些任務,這里有幾種類型的異步接口

    1,回調函數

    2,返回一個占位符(Future,Promise,Deferred)

    3,傳送一個隊列

    4,回調注冊

    一個簡單的同步異步函數

    

from tornado.httpclient import HTTPClient from tornado.concurrent import Future def synchronous_fetch(url):http_client = HTTPClient()def handle_response(response):callback(response.body)http_client.fetch(url,callbace=handle_response)

    在一次通過Future替代回調函數

    

def async_fetch_future(url):http_client=HTTPClient()my_future=Future()fetch_future=http_client.fetch(url)fetch_future.add_done_callback(lambda f:my_future.set_result(f.result))return my_future

    原始的Future是很復雜的,但是Futures是tornado中推薦使用的一種做法,因為他有兩個優勢

    錯誤處理是通過Future.result 函數可以簡單拋出一個異常,還有就是攜程兼容比較好

   

rom tornado import gen@gen.coroutine def fetch_coroutine(url):http_client = AsyncHTTPClient()response = yield http_client.fetch(url)raise gen.Return(response.body)

    語句?raise?gen.Return(response.body)?在 Python 2 中是人為設定的, 因為生成器不允許又返回值. 為了克服這個問題, Tornado 協程拋出了一個叫做?Return?的特殊異常. 協程將會像返回一個值一樣處理這個異常.在 Python 3.3+ 中,?return?response.body?將會達到同樣的效果.

?

二:協程

  tornado中推薦協程來編寫異步代碼,協程使用python中關鍵件yield替換鏈式回調實現掛起和繼續協程的執行(像在gevent中使用輕量級線程合作的方法有時也稱作為協程,但是在Tornado中所有的協程使用異步函數來實現明確的上下文切換)

  看下協程的代碼

from tornado import gen from tornado import HTTPClient def fetch_coroutie(url):http_client=AsyncHTTPClient()
  respone=yield http_client.fetch(url)

  # raise gen.Return(respone.body)
  
  return respone.body

?

   python3.5 async和awiat 

   python3.5 引入啦async和await 從tornado4.3開始,在協程基礎上你可以使用這個來代替yield,簡單的通過使用async def foo()來替代 @gen.coroutine 裝飾器,用await來代替yield,可以看下下面的例子

  

async def fetch_coroutine(url):http_client = AsyncHTTPClient()response = await http_client.fetch(url)return response.body

    一個含有yield的函數時是一個生成器,所有的生成器都是異步的,調用它時將會返回一個對象而不是將函數運行完成,@gen.coroutine修飾器通過yeild表達式通過產生一個Future對象和生成器進行通信

    可以看下一個協程裝飾器內部循環的簡單版本

    

def run(self):future=self.gen.send(self.next)def callback(f):self.next=f.result()self.run()future.add_done_callback(callback)

    

有時你并不想等待一個協程的返回值. 在這種情況下我們推薦你使用?IOLoop.spawn_callback, 這意味著?IOLoop?負責調用. 如果它失敗了,?IOLoop?會在日志中記錄調用棧: ?同時注意spawn_callback調用的函數,也必須是協程函數

# The IOLoop will catch the exception and print a stack trace in # the logs. Note that this doesn't look like a normal call, since # we pass the function object to be called by the IOLoop.
IOLoop.current().spawn_callback(divide, 1, 0)


  協程模式
   1,結合callbacks
      
為了使用回調來代替Future與異步代碼進行交互,將這個調用裝在task中,這將會在你生成的Future對象中添加一個回調參數
      
@gen.coroutine def call_task():yield gen.Task(some_function, other_args)#把yeild換成gen_Task

     2,調用阻塞函數

      在協程中調用阻塞函數的最簡單方法是使用ThreadPoolExecutor ?這將返回與協程兼容的Futures

      

thread_pool = ThreadPoolExecutor(4)@gen.coroutine def call_blocking():yield thread_pool.submit(blocking_func, args)

      3,并行

        協程裝飾器識別列表或者字典中的Futures,并且并行等待這些Fuures

    

@gen.coroutine def parallel_fetch(url1,url2):resp1,resp2 = yield [http_client.fetch(url1),http_client.fetch(url2)]@gen.coroutine def parallel_fetch_dict(urls):responses = yield {url: http_client.fetch(url)for url in urls}

      4,交叉存取技術(項目一般用到比較多)

        有時保存一個Future比立刻yield它更有用,你可以等待它之前執行其他操作

        

def get(self):fetch_future = self.fetch_next_chunk()while True:chunk = yield fetch_futureif chunk is None:breakself.write(chunk)fetch_future= self.fetch_next_chunk()yield self.flush()

      5,循環

        因為python無法使用forwhile循環yield迭代器,并且捕獲yield的返回結果,相反,你需要將循環和訪問結果區分開來,

      

import motor db = motor.MotorClient().test@gen.coroutine def loop_example(collection):cursor = db.collection.find()while (yield cursor.fetch_next):doc = cursor.next_object()

      6,在后臺運行

@gen.coroutine def minute_loop():while True:yield do_something()yield gen.sleep(60)# Coroutines that loop forever are generally started with # spawn_callback(). IOLoop.current().spawn_callback(minute_loop)

?

?

更過內容可以參考:http://tornado-zh-cn.readthedocs.io/zh_CN/latest/guide/coroutines.html#python-3-5-async-await

        

?

    

  

?

轉載于:https://www.cnblogs.com/1204guo/p/8533421.html

總結

以上是生活随笔為你收集整理的tornado 第一篇的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。