This example program creates a context using the context.WithCancel() method from the context package.
WithCancel
creates the context while returning a cancel function that can be called to prematurely cancel/end the context.
exec.CommandContext(ctx, ".\\test.exe", "e")
is exec.Command()
but with creating a context around the creation and execution of the sub process. Using that context, the execution of the sub process can now be ended prematurely.
The text.exe is another compiled and linked Go program, that just loops forever, printing "ENDLESS.." to the console.
As the example program calls cmd.Wait()
it waits for the sub process to end, either by it ending by itself od because of being killed by another system process.
Without ending the context, the sub process and so our program would run forever..
We will now start a go-routine and inside of it sleep for two seconds and call the created cancel()
method to kill the sub process.
As we can see, the main program ends right after that, so we successfully killed the sub process prematurely.
package main
import (
"context"
"fmt"
"os/exec"
"time"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// Start the process in the background
cmd := exec.CommandContext(ctx, ".\\test.exe", "e")
err := cmd.Start()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Process started with PID: %d\n", cmd.Process.Pid)
// by now, the test.exe sub process is running and I wrote test.exe to loop forever
// and print out the string "ENDLESS.." to the console.
// Start a co-routine that calls the cancel-Function after 2 Seconds
// By that, the created sub process will be killed and the current program will end
// as cmd.Wait() finishes
go func() {
time.Sleep(2 * time.Second)
cancel()
}()
// Wait for the process to complete
err = cmd.Wait()
if err != nil {
fmt.Printf("Error: %v\n", err)
}
fmt.Println("Process completed.")
}
package main
import (
"os"
"time"
)
func main() {
endless := os.Args[1]
if endless == "e" {
for {
println("ENDLESS..")
time.Sleep(5 * time.Second)
}
} else {
println("TEST")
}
}