Прекращение процесса, начатого с os/exec в Голанге
Есть ли способ завершить процесс, запущенный с os.exec в Golang? Например (от http://golang.org/pkg/os/exec/#example_Cmd_Start),
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)
Есть ли способ прервать этот процесс раньше времени, возможно, через 3 секунды?
Заранее спасибо
Ответы
Ответ 1
Завершение работы 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)
}
Завершение работы exec.Process
после тайм-аута:
// 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")
}
Либо процесс завершается, и его ошибка (если таковая имеется) получена через done
либо прошло 3 секунды, и программа завершается до завершения.
Ответ 2
Простая версия без выбора и каналов.
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)
}
Хорошо, после консультаций с опытным программистом, это, по-видимому, не является достаточным для решения проблемы. Поэтому, пожалуйста, обратитесь к принятому ответу.
Вот еще более короткая версия и очень прямолинейная. НО, возможно, у вас есть тонны подвесных горутов, если тайм-аут длинный.
func main() {
cmd := exec.Command("cat", "/dev/urandom")
cmd.Start()
go func(){
time.Sleep(timeout)
cmd.Process.Kill()
}()
return cmd.Wait()
}