Reputation: 4007
I have a child_process that takes 100 seconds to run. The "master" program will spawn the child_process and either waits for it to finish, or terminates it early.
Here is the code snippet of the master program. It fmt.Println
the progress and check its stdin
with a goroutine. Once "terminate" is received, the master passes the message to the child_process to interrupt it.
//master program
message := make(chan string)
go check_input(message)
child_process := exec.Command("child_process")
child_stdin := child_process.StdinPipe()
child_process.Start() //takes 100 sec to finish
loop:
for i=:1;i<=100;i++ {
select {
case <- message:
//end child process
child_stdin.Write([]byte("terminate\n"))
break loop
case <- time.After(1*time.Second):
fmt.Println(strconv.ItoA(i) + " % Complete") // update progress bar
}
child_process.Wait() //wait for child_process to be interrupted or finish
The "check_input" function is used in both the master program and child_process. It receives "terminate" message from stdin.
//check_input function
func check_input(msg chan string){
reader := bufio.NewReader(os.Stdin)
for {
line, err := reader.ReadString('\n')
if err != nil {
// You may check here if err == io.EOF
break
}
if strings.TrimSpace(line) == "terminate" {
msg <- "terminate"
}
}
}
It currently works with goroutine and chan.
My question is whether there is a better way to signal/kill/interrupt the child_process.
Upvotes: 4
Views: 3256
Reputation: 91193
You can use syscall.Kill
to send a signal to a child process providen you have its pid. For example:
syscall.Kill(cpid, syscall.SIGHUP)
Of course, the above is *nix specific.
Upvotes: 0