我可以无限期递归地提供TCL脚本吗?

时间:2017-04-06 13:24:35

标签: recursion tcl stack-overflow

我在TCL shell中运行了一个TCL脚本(synopsys黄金时段,如果它有任何区别)。 该脚本由/*Example 1*/ filename myfile "/tmp/file1"; data _null_; file myfile recfm=n; a=1; put a; run; filename myfile; /*Example 2*/ data _null_; file "/tmp/file2" recfm=n; a=1; put a; run; 从shell启动。 在脚本结束时调用source <script>后,脚本在经过特定时间间隔后递归调用自身。 我的问题有点学术性:如果脚本在这个方法中不断调用自己,是否会出现堆栈溢出问题?

如果我扩展问题:当TCL脚本获取另一个脚本时会发生什么?它是否为子进程分叉?如果是这样,那么每个调用都会向另一个子进行分叉,最终会堆积到一堆进程 - 但由于源命令本身不是并行的 - 所以没有分叉(根据我的理解)。

希望问题很清楚。 感谢。

2 个答案:

答案 0 :(得分:2)

简答:是的。

如果您使用的是Tcl 8.5或之前,,您将耗尽C堆栈。如果你这样做,有代码试图检测它并抛出一个软(catch能)错误。对于可以通过interp recursionlimit控制的递归次数也有(下限)限制。请注意,这是计算核心Tcl脚本解释器引擎的递归条目;它在脚本中不是完全递归级别,尽管它非常接近。

# Set the recursion limit for the current interpreter to 2000
interp recursionlimit {} 2000

默认值为1000,几乎适用于任何非递归算法。

在Tcl 8.6中,非递归执行引擎用于大多数命令(包括source)。这使得您的代码可以使用更多更大的递归深度,主要受限于您拥有多少通用内存。我已成功运行传统硬件上递归深度超过一百万的代码。

你仍然需要提高interp recursionlimit;默认的1000限制仍然存在,因为它捕获了更多的错误(即无意的递归)。只是你可以有意义地提高它。

答案 1 :(得分:0)

该命令不会分叉新进程。它就好像源文件中的行代替了源的调用一样。除非另有说明,否则它们由当前解释器解释。