协程栈是否以Lua,Python,Ruby或任何其他语言增长?

时间:2013-03-21 11:36:47

标签: stack-overflow coroutine stackless

有些语言支持确定性轻量级并发 - 协程。

  1. Lua - coroutine
  2. 无Stack-Python-tasklet
  3. Ruby - fiber
  4. 应该更多......但目前我没有太多想法。
  5. 无论如何,据我所知,它需要许多分离的堆栈,所以我想知道这些语言如何处理堆栈增长。这是因为我阅读了带有4KB的some mention about Ruby Fiber - 显然是一个很大的开销 - 并且他们将此作为防止堆栈溢出的功能进行宣传。但我不明白为什么他们只是说堆栈会自动增长。没有任何意义的VM - 不限于C堆栈 - 无法处理堆栈增长,但我无法证实这一点,因为我不太了解内部组件。

    他们如何处理这些微线程的堆栈增长?有没有明确/隐含的限制?或者只是清楚自动地处理?

1 个答案:

答案 0 :(得分:2)

对于红宝石:

根据这个google tech talk,ruby vm使用一个稍微hacky的系统,包括为每个线程提供一个C堆栈副本,然后每次在光纤之间切换时将该堆栈复制到主堆栈。这意味着Ruby仍然限制每个光纤具有超过4KB的堆栈,但如果您在深层嵌套的光纤之间切换,则解释器不会溢出。

对于python:

task-let仅在无堆栈变体中可用。每个线程都有自己的基于堆的堆栈,因为无堆栈python vm使用基于堆的堆栈。这种混乱本身仅限于堆栈增长中堆的大小。这意味着对于32位系统,仍然有效限制为1-4 GB。

对于Lua:

Lua使用基于堆的堆栈,因此本质上仅限于堆栈增长中堆的大小。每个协同程序在内存中都有自己的堆栈。这意味着对于32位系统,仍然有效限制为1-4 GB。

要在列表中添加更多内容,C#和VB.Net现在都支持async / await。这是一个允许程序执行耗时操作并且之后继续该功能的其余部分的系统。这是通过创建一个对象来实现的,该对象使用一个方法来调用,该方法被调用以进入方法的下一步,当您尝试获取结果和各种其他内部位置时调用该方法。原始方法将替换为创建对象的方法。这意味着递归深度不受影响,因为该方法在堆栈中的位置远远超过您预期的几步。