【问题标题】:use tornado coroutine in call stack在调用堆栈中使用 tornado 协程
【发布时间】:2015-03-03 08:18:27
【问题描述】:

我是 tornado 的新手,对 tornado 的协程有一些疑问。 如果我有一个调用堆栈看起来像:

func_a => func_b => func_c => func_d

func_d 是一个异步函数,我使用 yield 和 @gen.coroutine 装饰器。
就像这样:

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

我必须将yield@gen.coroutinefunc_cfunc_bfunc_a 一起使用吗?

【问题讨论】:

  • 这是否意味着 func a,b,c 是同步函数?
  • 同步的,函数a、b、c是否同步有区别吗?

标签: python tornado


【解决方案1】:

是的,你协程的所有调用者也必须是协程,并且它们必须产生你协程的结果。

为什么?没有执行 yield 语句,任何协程都无法进行 I/O。查看您的代码:它可能需要与服务器通信吗?然后它必须屈服。它的调用者也必须如此,依此类推,最终你已经屈服于事件循环。否则循环无法进行,I/O 不会完成。

这既是协程代码的技术要求,也是协程相对于线程的优势。通过查看代码,您总能知道何时会被打断:

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

有关重构协程的更多信息,请参阅:

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

【讨论】:

  • @tyouicn 还有什么我可以帮助你的吗,或者你会在 Stack Overflow 上接受我的回答为“正确”吗?
  • 这仍然不成立,因为有 await 关键字,对吧?我认为现在可以为此目的将 yield 替换为 await ,但我发现文档在这方面相当混乱,所以我不确定。
  • 所有协程调用者都必须是协程,这仍然是事实。您可以使用“async def”定义您的协程并使用“await”,或者在 Python 3.4 及更早版本中使用“gen.coroutine”和“yield”定义它们。见tornadoweb.org/en/latest/guide/coroutines.html
猜你喜欢
  • 2020-10-16
  • 1970-01-01
  • 1970-01-01
  • 2015-05-12
  • 2013-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-24
相关资源
最近更新 更多