2015-03-03 31 views
1

我是龍捲風新手,對龍捲風協程有一些疑問。 如果我有一個調用堆棧的樣子:在調用堆棧中使用龍捲風協程

func_a => func_b => func_c => func_d 

和func_d是一個異步功能,我用產量和@ gen.coroutine裝飾。
就像這樣:

@gen.coroutine 
def redis_data(self, id): 
    ret = yield asyn_function() 
    raise gen.Return(ret) 

我必須使用yield@gen.coroutinefunc_cfunc_bfunc_a

+0

這是否意味着FUNC A,B,C是syncornous功能? – laike9m 2015-03-03 10:39:13

+0

同步和如果函數a,b,c是同步的還是有一些區別嗎? – tyouicn 2015-03-06 08:28:20

回答

4

是的,你所有的協同程序的調用者也必須是協同程序,他們必須產生協程的結果。

爲什麼?沒有協程可以執行I/O而不執行yield語句。看看你的代碼:它可能需要與服務器交談?然後它必須屈服。因此,它的調用者必須遵循這個鏈條,這樣最終你已經屈服於事件循環。否則,循環無法進展,並且I/O無法完成。

這既是協程代碼的技術要求,也是協程對線程的優勢。你總是通過看你的代碼知道什麼時候你可以打斷:

https://glyph.twistedmatrix.com/2014/02/unyielding.html

更多關於重構協同程序,請參見:

http://emptysqua.re/blog/refactoring-tornado-coroutines/

+0

@tyouicn還有什麼我可以幫助你,或者你會接受我的答案作爲堆棧溢出「正確」? – 2015-03-03 21:40:18

+0

這還不成立,因爲有'await'關鍵字,對吧?我認爲現在可以用等待替代產量,但是我發現文檔在這方面相當混亂,所以我不確定。 – Zelphir 2016-11-11 19:02:50

+0

所有協程程序調用者都必須是協程程序,這仍然是事實。你可以用「async def」定義你的協程並使用「await」,或者在Python 3.4及更早的版本中用「gen.coroutine」和「yield」來定義它們。見http://www.tornadoweb.org/en/latest/guide/coroutines.html – 2016-11-11 19:44:59