Подтвердить что ты не робот

Прекращение процесса, начатого с 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 секунды?

Заранее спасибо

4b9b3361

Ответ 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()
}