patterngoCritical
Terminating a Process Started with os/exec in Golang
Viewed 0 times
withprocessterminatinggolangstartedexec
Problem
Is there a way to terminate a process started with os.exec in Golang? For example (from http://golang.org/pkg/os/exec/#example_Cmd_Start),
Is there a way to terminate that process ahead of time, perhaps after 3 seconds?
cmd := exec.Command("sleep", "5")
err := cmd.Start()
if err != nil {
log.Fatal(err)
}
log.Printf("Waiting for command to finish...")
err = cmd.Wait()
log.Printf("Command finished with error: %v", err)Is there a way to terminate that process ahead of time, perhaps after 3 seconds?
Solution
Run and terminate an
Run and terminate an
See this example in the Go docs
Legacy
Before Go 1.7, we didn't have the
Run and terminate an
Either the process ends and its error (if any) is received through
exec.Process:// Start a process:
cmd := exec.Command("sleep", "5")
if err := cmd.Start(); err != nil {
log.Fatal(err)
}
// Kill it:
if err := cmd.Process.Kill(); err != nil {
log.Fatal("failed to kill process: ", err)
}Run and terminate an
exec.Process after a timeout:ctx, cancel := context.WithTimeout(context.Background(), 3 * time.Second)
defer cancel()
if err := exec.CommandContext(ctx, "sleep", "5").Run(); err != nil {
// This will fail after 3 seconds. The 5 second sleep
// will be interrupted.
}See this example in the Go docs
Legacy
Before Go 1.7, we didn't have the
context package and this answer was different.Run and terminate an
exec.Process after a timeout using channels and a goroutine:// Start a process:
cmd := exec.Command("sleep", "5")
if err := cmd.Start(); err != nil {
log.Fatal(err)
}
// Wait for the process to finish or kill it after a timeout (whichever happens first):
done := make(chan error, 1)
go func() {
done <- cmd.Wait()
}()
select {
case <-time.After(3 * time.Second):
if err := cmd.Process.Kill(); err != nil {
log.Fatal("failed to kill process: ", err)
}
log.Println("process killed as timeout reached")
case err := <-done:
if err != nil {
log.Fatalf("process finished with error = %v", err)
}
log.Print("process finished successfully")
}Either the process ends and its error (if any) is received through
done or 3 seconds have passed and the program is killed before it's finished.Code Snippets
// Start a process:
cmd := exec.Command("sleep", "5")
if err := cmd.Start(); err != nil {
log.Fatal(err)
}
// Kill it:
if err := cmd.Process.Kill(); err != nil {
log.Fatal("failed to kill process: ", err)
}ctx, cancel := context.WithTimeout(context.Background(), 3 * time.Second)
defer cancel()
if err := exec.CommandContext(ctx, "sleep", "5").Run(); err != nil {
// This will fail after 3 seconds. The 5 second sleep
// will be interrupted.
}// Start a process:
cmd := exec.Command("sleep", "5")
if err := cmd.Start(); err != nil {
log.Fatal(err)
}
// Wait for the process to finish or kill it after a timeout (whichever happens first):
done := make(chan error, 1)
go func() {
done <- cmd.Wait()
}()
select {
case <-time.After(3 * time.Second):
if err := cmd.Process.Kill(); err != nil {
log.Fatal("failed to kill process: ", err)
}
log.Println("process killed as timeout reached")
case err := <-done:
if err != nil {
log.Fatalf("process finished with error = %v", err)
}
log.Print("process finished successfully")
}Context
Stack Overflow Q#11886531, score: 170
Revisions (0)
No revisions yet.