在TCL脚本中检测TCL后台进程的结束

时间:2012-08-24 15:29:16

标签: user-interface exec tcl background-process

我正在开发一个使用EXEC命令来运行make文件的程序。这可能需要很长时间,所以我想把它放在后台,所以GUI不会锁定。但是,我还希望禁用GUI,并且只在make文件编译时运行进度条。

那么如何在TCL中检测后台进度何时结束?

编辑:它变得更复杂,因为我的老板希望命令窗口保持打开(或可见),以便用户可以看到制作的进度并查看它是否有错误。

P.S。想要解决线程更容易吗?我需要一些方法来阻止GUI锁定(防止不响应)。'

编辑:GUI由TK制作。 我认为TK是单线程的,这会导致问题。或者它可能是默认为单线程,我想将其设置为多线程。

2 个答案:

答案 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。也许专家会帮助我。