1

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

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

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

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

4

1 回答 1

2

对于红宝石:

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

对于蟒蛇:

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

对于 Lua:

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

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

于 2013-06-04T11:49:23.697 回答