Timing out process execution

suggest change

There’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.

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:



Table Of Contents