我上的程序工作使用一个EXEC命令运行make文件。 这可能需要很长的时间,所以我希望把它的背景,使GUI不锁定。 不过我也想被禁用的图形用户界面和一个进度条只在make文件正在编制运行。
所以,我怎么能检测何时背景进展,TCL已完成?
编辑:因为我的老板要在命令窗口保持打开状态(或者是visable),使用户可以看到化妆的进度,看看它是否错误,问题就变得更复杂了。
PS会搞清楚线程更简单吗? 我需要一些方法来防止GUI抱死(防止无响应)“。
编辑:GUI与TK制成。 我认为TK是单线程的,这会导致问题。 或者,它可能是它默认为单线程,我想将它设置为多线程。
作为@格伦 - 杰克曼指出,使用fileevent是优选的(因为它应该到处)。
proc handle_bgexec {callback chan} {
append ::bgexec_data($chan) [read $chan]
if {[eof $chan]} {
# end of file, call the callback
{*}$callback $::bgexec_data($chan)
unset ::bgexec_data($chan)
}
}
proc bgexec {callback args} {
set chan [open "| $args" r]
fconfigure $chan -blocking false
fileevent $chan readable [list handle_bgexec $callback $chan]
return
}
调用此为bgexec job_done cmd /c start /wait cmd /c make all-all
。 job_done
它完成之后被调用用命令的输出。
也可以使用线程这个事情,但是这需要一个螺纹TCL版本(也就是现在的默认适用于所有平台据我所知,但旧版本的Tcl的ESP。UNIX下默认是不建立一个线程的Tcl)和Thread
包(其由缺省包括)。 一种方法来使用它与主题将是:
thread::create "[list exec cmd /c start /wait cmd /c make all-all];[list thread::send [thread::id] {callback code}];thread::exit"
如果您需要调用此定期它可能是值得使用的,而不是创建为每个作业一个新的只有一个工作线程。
编辑:添加/wait
作为参数来启动保持第一CMD运行。
cmd /c start /wait cmd /c make all-all
你想在管道运行make过程,并使用事件循环和fileevent以监测其进展情况(见http://wiki.tcl.tk/880 )
proc handle_make_output {chan} {
# The channel is readable; try to read it.
set status [catch { gets $chan line } result]
if { $status != 0 } {
# Error on the channel
puts "error reading $chan: $result"
set ::DONE 2
} elseif { $result >= 0 } {
# Successfully read the channel
puts "got: $line"
} elseif { [chan eof $chan] } {
# End of file on the channel
puts "end of file"
set ::DONE 1
} elseif { [chan blocked $chan] } {
# Read blocked. Just return
} else {
# Something else
puts "can't happen"
set ::DONE 3
}
}
set chan [open "|make" r]
chan configure $chan -blocking false
chan event $chan readable [list handle_make_output $chan]
vwait ::DONE
close $chan
我不能确定使用vwait
Tk的的事件循环中。 也许,专家会帮助我在这里。