我在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脚本获取另一个脚本时会发生什么?它是否为子进程分叉?如果是这样,那么每个调用都会向另一个子进行分叉,最终会堆积到一堆进程 - 但由于源命令本身不是并行的 - 所以没有分叉(根据我的理解)。
希望问题很清楚。 感谢。
答案 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)
该命令不会分叉新进程。它就好像源文件中的行代替了源的调用一样。除非另有说明,否则它们由当前解释器解释。