我目前有一个 GUI,经过一些自动化(使用期望)后,用户可以与 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
or的形式firstDead
)。while
我将交互的超时值设置为 1 秒,因此即使用户正在与该 telnet 会话进行交互,它也会被迫继续检查循环是否为真。一旦发送了 dead 信号,它就会等待确认进程已经死亡(通过vwait
)。
问题是一旦发送信号,循环永远不会意识到它应该死掉,除非它被赋予上下文来检查它。first
循环需要一直运行,直到它被or踢出secondDead
。所以在切换到下一个进程之前需要有某种形式的等待,让前一个进程的循环processInteraction
有控制权。
任何帮助将不胜感激。