Detect end of TCL background process in a TCL script

后端 未结 2 2020
难免孤独
难免孤独 2021-01-01 06:43

I\'m working on a program the uses an EXEC command to run a make file. This can take a long time so I want to put it in the background so the GUI doesn\'t lock up. However I

2条回答
  •  一整个雨季
    2021-01-01 07:43

    As @glenn-jackman pointed out, the use of fileevent is preferred (because it should work everywhere).

    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
    }
    

    Invoke this as bgexec job_done cmd /c start /wait cmd /c make all-all. job_done gets called with the output of the command after it finishes.

    It is also possible to use threads for this things, but this requires a threaded tcl build (which is now default for all platforms AFAIK, but older versions of Tcl esp. under unix don't build a threaded Tcl by default.) and the Thread package (which is included by default). An approach to use it with Threads would be:

    thread::create "[list exec cmd /c start /wait cmd /c make all-all];[list thread::send [thread::id] {callback code}];thread::exit"
    

    If you need to call this on a regular basis it might be worth to use only one worker thread instead of creating a new one for each job.

    Edit: Add /wait as parameter for start the keep the first cmd running.

    cmd /c start /wait cmd /c make all-all
    

提交回复
热议问题