Timing out process execution
suggest changeThere’s no guarantee that a process will finish running so you might want to add a timeout.
cmd := exec.Command("go", "version")
err := cmd.Start()
if err != nil {
log.Fatalf("cmd.Start() failed with '%s'\n", err)
}
var timedOut int32
timeout := 1 * time.Millisecond
stopTimer := time.AfterFunc(timeout, func() {
cmd.Process.Kill()
atomic.StoreInt32(&timedOut, 1)
})
err = cmd.Wait()
stopTimer.Stop()
didTimeout := atomic.LoadInt32(&timedOut) != 0
fmt.Printf("didTimeout: %v, err: %v\n", didTimeout, err)
didTimeout: true, err: signal: killed
Before calling cmd.Wait()
we use time.AfterFunc()
to kill the process after a timeout expired.
cmd.Process.Kill()
makes cmd.Wait()
exit with an error (signal: killed
on Unix).
If cmd.Wait()
finishes before a timeout, we cancel the timer.
Variable timedOut
is int32
and not bool
.
We use atomic.StoreInt32
and atomic.LoadInt32
because there is a subtle timing issues.
If a process finishes as usual, after cmd.Wait()
exits and before we call stopTimer.Stop()
, the timer might expire and execute the function anyway.
This is exceedingly unlikely but something to keep in mind.
Found a mistake? Have a question or improvement idea?
Let me know.
Table Of Contents