Tornado 4.0 已經(jīng)發(fā)布了很長(zhǎng)一段時(shí)間了, 新版本廣泛的應(yīng)用了協(xié)程(Future)特性. 我們目前已經(jīng)將 Tornado 升級(jí)到最新版本, 而且也大量的使用協(xié)程特性.
很長(zhǎng)時(shí)間沒(méi)有更新博客, 今天就簡(jiǎn)單介紹下 Tornado 協(xié)程實(shí)現(xiàn)原理, Tornado 的協(xié)程是基于 Python 的生成器實(shí)現(xiàn)的, 所以首先來(lái)回顧下生成器.
生成器
Python 的生成器可以保存執(zhí)行狀態(tài) 并在下次調(diào)用的時(shí)候恢復(fù), 通過(guò)在函數(shù)體內(nèi)使用 yield 關(guān)鍵字 來(lái)創(chuàng)建一個(gè)生成器, 通過(guò)內(nèi)置函數(shù) next 或生成器的 next 方法來(lái)恢復(fù)生成器的狀態(tài).
def test(): yield 1
我們調(diào)用 test 函數(shù), 此時(shí)并不會(huì)返回結(jié)果, 而是會(huì)返回一個(gè)生成器
>>> test()<generator object test at 0x100b3b320>
我們調(diào)用其 next 方法則返回 yield 關(guān)鍵字之后的內(nèi)容.
>>> t = test()>>> t.next()1
如果我們接著調(diào)用 next 方法, 后面又沒(méi)有 yield 關(guān)鍵字繼續(xù)返回的話, 會(huì)拋出一個(gè) StopIteration 異常.
yield 關(guān)鍵字不僅僅能從生成器內(nèi)部返回狀態(tài), 同時(shí)也可以將外部信息傳遞到生成器內(nèi)部, 通過(guò)將 yeild 關(guān)鍵里賦值給變量, 并調(diào)用生成器的 send 方法來(lái)將對(duì)象傳遞到生成器 內(nèi)部. 需要注意的是生成器的開(kāi)始必須調(diào)用其 next 方法, 后面 send 方法調(diào)用的同時(shí) 也會(huì)觸發(fā) next 動(dòng)作. 如果沒(méi)有變量接收 yield 關(guān)鍵字那么 send 傳遞的值將會(huì) 被丟棄.
>>> def test(): a = yield print(a)
首先調(diào)用 next 上面函數(shù)返回的生成器將返回 None, 如果這時(shí)候直接調(diào)用 next 將 會(huì)給生成器發(fā)送 None, 如果調(diào)用 send 發(fā)送一個(gè)值, 將打印這個(gè)值并拋出 StopIteration 異常.
一個(gè)簡(jiǎn)單地協(xié)程
以上就是實(shí)現(xiàn)協(xié)程的所有基礎(chǔ), 為了加深理解, 我們這里寫(xiě)一個(gè)小例子, 例子我們只使用協(xié)程 開(kāi)啟兩個(gè)甚至多個(gè)死循環(huán), 下面就是一個(gè)極其簡(jiǎn)單地例子::
#!/usr/bin/env python# -*- coding:utf-8 -*-
from __future__ import absolute_import, print_function, division, with_statementdef loop1(): """ 循環(huán)1負(fù)責(zé)拋出一個(gè)函數(shù)和對(duì)應(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é)程異步的例子
新聞熱點(diǎn)
疑難解答
圖片精選