2013-11-14 5 views
2

Допустим, у меня есть сценарий tcl, который обычно должен выполняться менее чем за минуту. Как я могу убедиться, что сценарий NEVER занимает больше, чем «x» минут/секунд для выполнения, и если это так, то сценарий должен быть просто остановился.Как грациозно убить невосприимчивый скрипт tcl?

Например, если сценарий занял более 100 секунд, я должен иметь возможность автоматически переключать управление на функцию очистки, которая изящно закончила бы скрипт, чтобы все данные из сценария выполнялись до сих пор но я также гарантирую, что это не займет слишком много времени или застрянет бесконечно.

Я не уверен, что это можно сделать в tcl - любая помощь или указатели будут приветствоваться.

ответ

0

Должен быть цикл, который вы беспокоитесь, может занять более 100 секунд, да? Сохраните clock seconds (текущее время), прежде чем вводить цикл, и проверьте время в конце каждой итерации, чтобы узнать, прошло ли более 100 секунд.

Если по каким-то причинам это невозможно, вы можете попробовать разработки что-то с помощью after —, который, стартует таймер обратного вызова, которая устанавливает (или сбросы) некоторые глобальной переменной, что ваш выполнение кода осознает — так, что обнаружение, оно может попытаться выйти.

+0

На самом деле это не цикл - скорее список команд, которые нужно запустить. Каждая команда может занять несколько секунд, но в некоторых случаях один из них может застрять, заставляя скрипт застрять навсегда. – egorulz

4

Вы можете использовать interp limit при использовании детского интерпретатора.

Обратите внимание, что это приведет к ошибке, которую невозможно устранить, если вы хотите очистить вас, чтобы удалить ограничение в родительской интерпретации.

set interp [interp create] 
# initialize the interp 
interp eval $interp { 
    source somestuff.tcl 
} 
# Add the limit. From now you have 60 seconds or an error will be thrown 
interp limit $interp time -seconds [clock seconds] -milliseconds 60000 
set errorcode [catch {interp eval {DoExpensiveStuff}} res opts] 
# remove the limit so you can cleanup the mess if needed. 
interp limit $interp time -seconds {} 
if {$errorcode} { 
    # Do some cleanup here 
} 
# delete the interp, or reuse it? 
interp delete $interp 
# And what shall be done with the error? Throw it. 
return -options $opt $res 

Ограничения по ресурсам - лучшая ставка с Tcl, но они не являются пуленепробиваемыми. Tcl не может (и не будет) прерывать процедуры C, и есть некоторые способы, чтобы ядро ​​Tcl делало некоторые тяжелые работы.

+1

C код должен проверить, превышены ли какие-либо ограничения; вот для чего нужен Tcl_LimitCheck'. –

Смежные вопросы