2012-08-09 10 views
44

C'è un modo per terminare un processo avviato con os.exec in Golang? Per esempio (da http://golang.org/pkg/os/exec/#example_Cmd_Start),Terminare un processo avviato con os/exec in Golang

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) 

C'è un modo di interrompere quel processo prima del tempo, forse dopo 3 secondi?

Grazie in anticipo

risposta

88

Dopo aver avviato il comando:

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: ", err) 
    } 
    log.Println("process killed as timeout reached") 
case err := <-done: 
    if err != nil { 
     log.Printf("process done with error = %v", err) 
    } else { 
     log.Print("process done gracefully without error") 
    } 
} 

O:

  1. termina il processo e il suo errore (se presente) viene ricevuto attraverso done
  2. 3 secondi sono passati e il programma è stato ucciso.
+5

Nota: dopo aver eliminato il processo, Wait() restituirà. Dovresti eseguire una procedura di estrazione dopo 'err: = cmd.Process.Kill()' per evitare perdite di memoria. –

+0

Grazie. Sembra essere più o meno quello che stavo cercando. – Tech163

+0

@StephenWeinberg Proprio così, aggiungerò questo. –

5

Una versione più semplice senza selezione e canali.

func main() { 
    cmd := exec.Command("cat", "/dev/urandom") 
    cmd.Start() 
    timer := time.AfterFunc(1*time.Second, func() { 
     err := cmd.Process.Kill() 
     if err != nil { 
      panic(err) // panic as can't kill a process. 
     } 
    }) 
    err := cmd.Wait() 
    timer.Stop() 

    // read error from here, you will notice the kill from the 
    fmt.Println(err) 
} 

Bene, dopo aver consultato qualche programmatore esperto andare, questo non è apparentemente un Goly modo sufficiente a risolvere il problema. Quindi, per favore, fai riferimento alla risposta accettata.


Ecco una versione ancora più breve, e molto semplice. MA, forse con tonnellate di goroutines sospese se il timeout è lungo.

func main() { 
    cmd := exec.Command("cat", "/dev/urandom") 
    cmd.Start() 
    go func(){ 
     time.Sleep(timeout) 
     cmd.Process.Kill() 
    }() 
    return cmd.Wait() 
} 
Problemi correlati