欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

簡單介紹Python的Tornado框架中的協(xié)程異步實(shí)現(xiàn)原理

 更新時(shí)間:2015年04月23日 17:23:22   作者:C Wong  
這篇文章主要介紹了簡單介紹Python的Tornado框架中的協(xié)程異步實(shí)現(xiàn)原理,作者基于Python的生成器講述了Tornado異步的特點(diǎn),需要的朋友可以參考下

Tornado 4.0 已經(jīng)發(fā)布了很長一段時(shí)間了, 新版本廣泛的應(yīng)用了協(xié)程(Future)特性. 我們目前已經(jīng)將 Tornado 升級到最新版本, 而且也大量的使用協(xié)程特性.

很長時(shí)間沒有更新博客, 今天就簡單介紹下 Tornado 協(xié)程實(shí)現(xiàn)原理, Tornado 的協(xié)程是基于 Python 的生成器實(shí)現(xiàn)的, 所以首先來回顧下生成器.
生成器

Python 的生成器可以保存執(zhí)行狀態(tài) 并在下次調(diào)用的時(shí)候恢復(fù), 通過在函數(shù)體內(nèi)使用 yield 關(guān)鍵字 來創(chuàng)建一個(gè)生成器, 通過內(nèi)置函數(shù) next 或生成器的 next 方法來恢復(fù)生成器的狀態(tài).

def test():
  yield 1

我們調(diào)用 test 函數(shù), 此時(shí)并不會返回結(jié)果, 而是會返回一個(gè)生成器

>>> test()
<generator object test at 0x100b3b320>

我們調(diào)用其 next 方法則返回 yield 關(guān)鍵字之后的內(nèi)容.

>>> t = test()
>>> t.next()
1

如果我們接著調(diào)用 next 方法, 后面又沒有 yield 關(guān)鍵字繼續(xù)返回的話, 會拋出一個(gè) StopIteration 異常.

yield 關(guān)鍵字不僅僅能從生成器內(nèi)部返回狀態(tài), 同時(shí)也可以將外部信息傳遞到生成器內(nèi)部, 通過將 yeild 關(guān)鍵里賦值給變量, 并調(diào)用生成器的 send 方法來將對象傳遞到生成器 內(nèi)部. 需要注意的是生成器的開始必須調(diào)用其 next 方法, 后面 send 方法調(diào)用的同時(shí) 也會觸發(fā) next 動作. 如果沒有變量接收 yield 關(guān)鍵字那么 send 傳遞的值將會 被丟棄.

>>> def test():
  a = yield
  print(a)

首先調(diào)用 next 上面函數(shù)返回的生成器將返回 None, 如果這時(shí)候直接調(diào)用 next 將 會給生成器發(fā)送 None, 如果調(diào)用 send 發(fā)送一個(gè)值, 將打印這個(gè)值并拋出 StopIteration 異常.
一個(gè)簡單地協(xié)程

以上就是實(shí)現(xiàn)協(xié)程的所有基礎(chǔ), 為了加深理解, 我們這里寫一個(gè)小例子, 例子我們只使用協(xié)程 開啟兩個(gè)甚至多個(gè)死循環(huán), 下面就是一個(gè)極其簡單地例子::

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from __future__ import absolute_import, print_function, division, with_statement

def loop1():
  """ 循環(huán)1負(fù)責(zé)拋出一個(gè)函數(shù)和對應(yīng)的參數(shù), 并接收結(jié)果
  """
  a = 0
  ret = 1
  while True:
    ret = yield sum, [a, ret]
    a, ret = ret, a
    print("Loop1 ret", ret)

def loop2():
  """ 循環(huán)2 負(fù)責(zé)接收函數(shù)并計(jì)算結(jié)果, 然后 yield 出結(jié)果
  """
  while True:
    func, args = yield
    yield func(args)
    print("Loop2")


l1 = loop1()
l2 = loop2()
tmp = l1.next()

for i in range(10):
  l2.next()
  ret = l2.send(tmp)
  tmp = l1.send(ret)


上面例子里 loop1 負(fù)責(zé)產(chǎn)生任務(wù), loop2 負(fù)責(zé)執(zhí)行任務(wù), 主循環(huán)負(fù)責(zé)調(diào)度任務(wù)并將任務(wù)結(jié)果發(fā)回給 任務(wù)產(chǎn)生者.
Tornado 如何做的

我們首先看一個(gè)使用 Tornado 協(xié)程異步的例子

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from __future__ import absolute_import, print_function, division, with_statement

from tornado import gen
from tornado import web
from tornado import httpclient


class ActionHandler(web.RequestHandler):

  @gen.coroutine
  def get(self):
    response = yield httpclient.AsyncHTTPClient().fetch("http://www.linuxzen.com")

    # ...

其實(shí)原理在上面簡單地例子里已經(jīng)講清楚了, 我們來簡單分析一遍上面的例子, 首先 Tornado 得到 ActionHandler.get 方法拋出(next)的一個(gè)任務(wù), 然后異步的去執(zhí)行任務(wù), 當(dāng)任務(wù)(網(wǎng)絡(luò)請求)結(jié)束或 異常時(shí) Tornado 取得事件通知然后將結(jié)果放回(send)到該方法中讓該方法繼續(xù)執(zhí)行.

由于是異步的, 調(diào)用這個(gè)方法并不會阻塞其他任務(wù)執(zhí)行.

這時(shí)候我們的方法其實(shí)就是上個(gè)例子 loop1 函數(shù), 而 Tornado 調(diào)度并執(zhí)行了其拋出的任務(wù).
總結(jié)

Tornado 的協(xié)程異步可以讓異步看起來是順序執(zhí)行的, 可以從一大串的 callback 中解脫出來.

Tornado 的協(xié)程異步并不是這三言兩語能說清楚的, 其中有很復(fù)雜的封裝和傳遞, 有興趣可以自己 閱讀源碼.

相關(guān)文章

  • pandas對齊運(yùn)算的實(shí)現(xiàn)示例

    pandas對齊運(yùn)算的實(shí)現(xiàn)示例

    本文主要介紹了pandas對齊運(yùn)算的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • python多線程實(shí)現(xiàn)動態(tài)圖繪制

    python多線程實(shí)現(xiàn)動態(tài)圖繪制

    這篇文章主要介紹了python多線程實(shí)現(xiàn)動態(tài)圖繪制,文章基于Python的相資料展開動態(tài)圖的繪制相關(guān)內(nèi)容,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-04-04
  • NumPy-ndarray 的數(shù)據(jù)類型用法說明

    NumPy-ndarray 的數(shù)據(jù)類型用法說明

    這篇文章主要介紹了NumPy-ndarray 的數(shù)據(jù)類型用法說明,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • Python如何將控制臺輸出另存為日志文件

    Python如何將控制臺輸出另存為日志文件

    這篇文章主要介紹了Python如何將控制臺輸出另存為日志文件問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • 利用Python實(shí)現(xiàn)無損GIF動圖的制作

    利用Python實(shí)現(xiàn)無損GIF動圖的制作

    這篇文章主要為大家詳細(xì)介紹了如何利用Python實(shí)現(xiàn)無損GIF動圖的制作,文中的實(shí)現(xiàn)方法講解詳細(xì),對我們學(xué)習(xí)Python有一定的幫助,需要的可以參考一下
    2023-04-04
  • Python數(shù)據(jù)結(jié)構(gòu)與算法中的隊(duì)列詳解(2)

    Python數(shù)據(jù)結(jié)構(gòu)與算法中的隊(duì)列詳解(2)

    這篇文章主要為大家詳細(xì)介紹了Python中的隊(duì)列,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • Python隨機(jī)數(shù)用法實(shí)例詳解【基于random模塊】

    Python隨機(jī)數(shù)用法實(shí)例詳解【基于random模塊】

    這篇文章主要介紹了Python隨機(jī)數(shù)用法,結(jié)合實(shí)例形式分析了基于random模塊的各種隨機(jī)數(shù)操作常用技巧,需要的朋友可以參考下
    2017-04-04
  • python遍歷迭代器自動鏈?zhǔn)教幚頂?shù)據(jù)的實(shí)例代碼

    python遍歷迭代器自動鏈?zhǔn)教幚頂?shù)據(jù)的實(shí)例代碼

    迭代器也是用來遍歷對象成員的,下面這篇文章主要給大家介紹了關(guān)于python遍歷迭代器自動鏈?zhǔn)教幚頂?shù)據(jù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-01-01
  • Python爬蟲爬取微信朋友圈

    Python爬蟲爬取微信朋友圈

    這篇文章主要介紹了Python爬蟲爬取微信朋友圈的方法,文中講解非常細(xì)致,幫助大家更好的理解和學(xué)習(xí)Python爬蟲,感興趣的朋友可以了解下
    2020-08-08
  • Python操作lxml庫之基礎(chǔ)使用篇

    Python操作lxml庫之基礎(chǔ)使用篇

    lxml庫是python的第三方庫,安裝方式也是十分簡單,下面這篇文章主要給大家介紹了關(guān)于Python操作lxml庫之基礎(chǔ)使用篇的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12

最新評論