Search code examples
tclexecpid

TCL wait for exec background job to finish


How do I get notification that a job that I launched in TCL via exec has finished?

set pid [ exec job & ]
while {<some_magic>} {puts "" waiting for $pid to finish ; sleep 1}
puts "Job $pid has finished. Now let's collect results."

The whole idea is that in reality I want to launch many jobs and then need to monitor when they're done.

Your feedback is much appreciated.

Best, Gert


Solution

  • On Unix, the result of exec is a process ID. There are all sorts of ways of checking whether a process exists; one of the neatest is to do:

    set running [file exists /proc/$pid]
    

    But that's not portable. (It works on Linux and, IIRC, Solaris. It doesn't work on OSX, and it's not meaningful at all on Windows of course.)

    Another approach is to do:

    set finished [catch {exec ps -p $pid >/dev/null}]
    # Note the inverted sense of result compared with previous code sample
    

    This works on any Unix that has ps (i.e., all of them) and where that ps accepts -p to mean “just talk about the following process ID”. So if you're running on BSD (other than OSX, where I've tested it), you might have problems. Test it!

    Apart from that, you can also use the TclX extension's signal command to detect a SIGCHLD and act on that.


    The most portable method of all (i.e., works on Windows and all Unixes) is to use open to make a pipeline and then use fileevent to detect the termination of the process. See this Stack Overflow question for more details: Detect end of TCL background process in a TCL script