我可以无限期地递归获取 TCL 脚本吗?
Can I recursively source a TCL script indefinitely?
我在 TCL shell 中有一个 TCL 脚本 运行(synopsys primetime,如果有任何区别的话)。
该脚本由 source <script>
来自 shell。
在经过特定时间间隔后,脚本通过在脚本末尾调用 source <script>
递归调用自身。
我的问题有点学术性:如果脚本在这种方法中不断调用自身,是否会出现堆栈溢出问题?
如果我扩展问题:当一个 TCL 脚本获取另一个脚本时会发生什么?它会分叉到子进程吗?如果是这样,那么每次调用都会分叉到另一个子进程,最终会堆积成一堆进程 - 但由于 source 命令本身不是并行的 - 没有分叉(根据我的理解)。
希望问题很清楚。
谢谢
简答:是。
如果您使用的是 Tcl 8.5 或更早版本, 您将 运行 超出 C 堆栈。有代码可以尝试检测它并在检测到时抛出一个软 (catch
able) 错误。可以完成的递归次数也有(下)限制,可通过 interp recursionlimit
控制。请注意,这是计算核心 Tcl 脚本解释器引擎的递归条目;它不是完全脚本中的递归级别,尽管它非常接近。
# Set the recursion limit for the current interpreter to 2000
interp recursionlimit {} 2000
默认值为 1000,这对于几乎所有非递归算法都足够了。
在 Tcl 8.6 中, 非递归执行引擎用于大多数命令(包括 source
)。这使您的代码可以使用 much 更大的递归深度,主要受限于您拥有多少通用内存。我已经在传统硬件上成功 运行 递归深度超过一百万的代码。
尽管如此,您仍然需要提高 interp recursionlimit
;默认的 1000 限制仍然存在,因为它捕获的错误(即无意的递归)多于未捕获的错误。只是你可以有意义地提高它。
该命令不会分叉新进程。它的行为就好像源文件中的行代替了源代码的调用。除非您另有说明,否则它们由当前解释器解释。
我在 TCL shell 中有一个 TCL 脚本 运行(synopsys primetime,如果有任何区别的话)。
该脚本由 source <script>
来自 shell。
在经过特定时间间隔后,脚本通过在脚本末尾调用 source <script>
递归调用自身。
我的问题有点学术性:如果脚本在这种方法中不断调用自身,是否会出现堆栈溢出问题?
如果我扩展问题:当一个 TCL 脚本获取另一个脚本时会发生什么?它会分叉到子进程吗?如果是这样,那么每次调用都会分叉到另一个子进程,最终会堆积成一堆进程 - 但由于 source 命令本身不是并行的 - 没有分叉(根据我的理解)。
希望问题很清楚。 谢谢
简答:是。
如果您使用的是 Tcl 8.5 或更早版本, 您将 运行 超出 C 堆栈。有代码可以尝试检测它并在检测到时抛出一个软 (catch
able) 错误。可以完成的递归次数也有(下)限制,可通过 interp recursionlimit
控制。请注意,这是计算核心 Tcl 脚本解释器引擎的递归条目;它不是完全脚本中的递归级别,尽管它非常接近。
# Set the recursion limit for the current interpreter to 2000
interp recursionlimit {} 2000
默认值为 1000,这对于几乎所有非递归算法都足够了。
在 Tcl 8.6 中, 非递归执行引擎用于大多数命令(包括 source
)。这使您的代码可以使用 much 更大的递归深度,主要受限于您拥有多少通用内存。我已经在传统硬件上成功 运行 递归深度超过一百万的代码。
尽管如此,您仍然需要提高 interp recursionlimit
;默认的 1000 限制仍然存在,因为它捕获的错误(即无意的递归)多于未捕获的错误。只是你可以有意义地提高它。
该命令不会分叉新进程。它的行为就好像源文件中的行代替了源代码的调用。除非您另有说明,否则它们由当前解释器解释。