Zhe Hu
Zhe Hu

Reputation: 4007

how to interrupt child process with golang goroutine

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

Answers (1)

zzzz
zzzz

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

Related Questions