У меня есть сценарий TCL, работающий внутри оболочки TCL (в прайм-тайм synopsys, если это имеет какое-либо значение). Сценарий инициируется source <script> из оболочки. Скрипт вызывает себя рекурсивно через определенный промежуток времени, вызывая source <script> в конце скрипта. Мой вопрос немного академичен: может ли быть проблема переполнения стека, если скрипт продолжает вызывать себя в этом методе?

Если я раскрою вопрос: что происходит, когда скрипт TCL использует другой скрипт? Разветвляется ли это на дочерний процесс? если так, то каждый вызов разветвляется другому дочернему элементу, который в конечном итоге будет складываться в кучу процессов - но поскольку сама исходная команда не параллельна - разветвления нет (насколько я понимаю).

Надеюсь, вопрос ясен. Спасибо.

1
Sancho Pancho 6 Апр 2017 в 16:24

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 остается, потому что он улавливает больше ошибок (то есть непреднамеренных рекурсий), чем нет. Просто вы можете значительно повысить его.

2
Donal Fellows 6 Апр 2017 в 14:51

Команда не разворачивает новый процесс. Это действует так, как если бы строки в исходных файлах были там вместо вызова источника. Они интерпретируются текущим переводчиком, если не указано иное.

0
Peter Lewerin 7 Апр 2017 в 01:08