我正在开发一个使用EXEC命令来运行make文件的程序。这可能需要很长时间,所以我想把它放在后台,所以GUI不会锁定。但是,我还希望禁用GUI,并且只在make文件编译时运行进度条。
那么如何在TCL中检测后台进度何时结束?
编辑:它变得更复杂,因为我的老板希望命令窗口保持打开(或可见),以便用户可以看到制作的进度并查看它是否有错误。
P.S。想要解决线程更容易吗?我需要一些方法来阻止GUI锁定(防止不响应)。'
编辑:GUI由TK制作。 我认为TK是单线程的,这会导致问题。或者它可能是默认为单线程,我想将其设置为多线程。
答案 0 :(得分:2)
正如@ glenn-jackman指出的那样,首选使用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构建(现在所有平台AFAIK都是默认的,但是unix下的旧版本的Tcl尤其不构建一个线程化的Tcl默认。)和Thread
包(默认包含)。将它与Threads一起使用的方法是:
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
答案 1 :(得分:0)
您希望在管道中运行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
我不确定在Tk的事件循环中使用vwait
。也许专家会帮助我。