【问题标题】:Does coroutine stacks grow in Lua, Python, Ruby or any other languages?协程堆栈是否在 Lua、Python、Ruby 或任何其他语言中增长?
【发布时间】:2013-03-10 21:34:37
【问题描述】:

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

  1. Lua - 协程
  2. 无堆栈 Python - tasklet
  3. 红宝石 - 纤维
  4. 应该还有更多...但目前我没有太多想法。

据我所知,它需要许多分离的堆栈,所以我想知道这些语言如何处理堆栈增长。这是因为我阅读了some mention about Ruby Fiber,它带有 4KB - 显然开销很大 - 他们将其宣传为防止堆栈溢出的功能。但我不明白为什么他们只是说堆栈会自动增长。虚拟机(不限于 C 堆栈)无法处理堆栈增长是没有意义的,但我无法确认这一点,因为我不太了解内部结构。

他们如何处理这类微线程上的堆栈增长?是否有任何显式/隐式限制?或者只是会被清晰自动地处理?

【问题讨论】:

    标签: stack-overflow coroutine stackless


    【解决方案1】:

    对于红宝石:

    根据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。这是一个允许程序执行耗时操作并让该功能的其余部分在之后继续的系统。这是通过创建一个对象来表示具有单个方法的方法来实现的,该方法被调用以前进到方法中的下一步,当您尝试获取结果和各种其他内部位置时调用该方法。原始方法被替换为创建对象的方法。这意味着递归深度不会受到影响,因为该方法永远不会比您预期的堆栈更进一步。

    【讨论】:

      猜你喜欢
      • 2016-12-21
      • 2012-10-08
      • 1970-01-01
      • 2011-08-02
      • 1970-01-01
      • 1970-01-01
      • 2011-02-21
      • 1970-01-01
      • 2013-10-28
      相关资源
      最近更新 更多