В настоящее время у меня есть графический интерфейс, который после некоторой автоматизации (с использованием ожидания) позволяет пользователю взаимодействовать с одним из 10 telnet-соединений. Взаимодействие осуществляется с помощью следующего цикла:
#After selecting an item from the menu, this allows the user to interact with that process
proc processInteraction {whichVariable id id_list user_id} {
if {$whichVariable == 1} {
global firstDead
set killInteract $firstDead
} elseif {$whichVariable == 2} {
global secondDead
set killInteract $secondDead
}
global killed
set totalOutput ""
set outputText ""
#set killInteract 0
while {$killInteract == 0} {
set initialTrue 0
if {$whichVariable == 1} {
global firstDead
set killInteract $firstDead
} elseif {$whichVariable == 2} {
global secondDead
set killInteract $secondDead
}
puts "$id: $killInteract"
set spawn_id [lindex $id_list $id]
global global_outfile
interact {
-i $spawn_id
eof {
set outputText "\nProcess closed.\n"
lset deadList $id 1
puts $outputText
#disable the button
disableOption $id $numlcp
break
}
-re (.+) {
set outputText $interact_out(0,string)
append totalOutput $outputText
#-- never looks at the following string as a flag
send_user -- $outputText
#puts $killInteract
continue
}
timeout 1 {
puts "CONTINUE"
continue
}
}
}
puts "OUTSIDE"
if {$killInteract} {
puts "really killed in $id"
set killed 1
}
}
При выборе нового процесса предыдущий должен быть уничтожен. Раньше у меня было это, когда при нажатии кнопки он просто снова входит в этот цикл. В конце концов я понял, что циклы while никогда не прекращались, и после 124 нажатий кнопок он вылетает (stackoverflow =P). Они не работают в фоновом режиме, но находятся в стеке. Поэтому мне нужен был способ убить цикл в функции processInteraction
при запуске нового процесса. Вот моя последняя попытка решения после многих неудач:
proc killInteractions {} {
#global killed
global killInteract
global first
global firstDead
global secondDead
global lastAssigned
#First interaction
if {$lastAssigned == 0} {
set firstDead 0
set secondDead 1
set lastAssigned 1
#firstDead was assigned last, kill the first process
} elseif {$lastAssigned == 1} {
set firstDead 1
set secondDead 0
set lastAssigned 2
vwait killed
#secondDead was assigned last, kill the second process
} elseif {$lastAssigned == 2} {
set secondDead 1
set firstDead 0
set lastAssigned 1
vwait killed
}
return $lastAssigned
}
killInteractions
вызывается при нажатии кнопки. Скрипт зависает на vwait
. Я знаю, что код кажется немного странным/шатким для обработки процессов с двумя переменными, но это была отчаянная последняя попытка заставить это работать.
Мертвый сигнал отправляется правильному процессу (в виде secondDead
или firstDead
). У меня установлено значение тайм-аута 1 секунда для взаимодействия, так что он вынужден продолжать проверять, является ли цикл while
истинным, даже когда пользователь взаимодействует с этим сеансом telnet. После того, как мертвый сигнал отправлен, он ожидает подтверждения того, что процесс умер (через vwait
).
Проблема в том, что после отправки сигнала цикл никогда не поймет, что он должен умереть, если ему не будет предоставлен контекст для его проверки. Цикл должен выполняться до тех пор, пока он не будет остановлен first
или secondDead
. Таким образом, перед переключением на следующий процесс должна быть какая-то форма ожидания, позволяющая циклу в processInteraction
предыдущего процесса иметь контроль.
Любая помощь будет принята с благодарностью.
global killed
в killInteractions закомментирована? Вы уверены, чтоkilled
правильно устанавливается processInteraction? - person bovine   schedule 12.06.2012vwait
всегда разрешает имена переменных относительно глобального пространства имен; если в них нет::
, они глобальные. - person Donal Fellows   schedule 13.06.2012