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

Проверьте, существует ли процесс в пути

Если у меня есть PID процесса, os.FindProcess достаточно, чтобы проверить существующий процесс? Я имею в виду, если он возвращает err, могу ли я предположить, что он был завершен (или убит)?

Edit:

Я только что написал оберточную функцию вокруг kill -s 0 (старое тестирование процесса bash). Это работает без каких-либо проблем, но я по-прежнему счастлив, если к этой проблеме есть другие решения (с библиотеками go).:

func checkPid(pid int) bool {
    out, err := exec.Command("kill", "-s", "0", strconv.Itoa(pid)).CombinedOutput()
    if err != nil {
        log.Println(err)
    }

    if string(out) == "" {
        return true // pid exist
    }
    return false
}
4b9b3361

Ответ 1

Вот традиционный unix-способ увидеть, жив ли процесс - отправьте ему сигнал 0 (как вы делали со своим примером bash).

От kill(2):

   If  sig  is 0, then no signal is sent, but error checking is still per‐
   formed; this can be used to check for the existence of a process ID  or
   process group ID.

И переведен в Go

package main

import (
    "fmt"
    "log"
    "os"
    "strconv"
    "syscall"
)

func main() {
    for _, p := range os.Args[1:] {
        pid, err := strconv.ParseInt(p, 10, 64)
        if err != nil {
            log.Fatal(err)
        }
        process, err := os.FindProcess(int(pid))
        if err != nil {
            fmt.Printf("Failed to find process: %s\n", err)
        } else {
            err := process.Signal(syscall.Signal(0))
            fmt.Printf("process.Signal on pid %d returned: %v\n", pid, err)
        }

    }
}

Когда вы запустите его, вы получите это, показывая, что процесс 123 мертв, процесс 1 жив, но не принадлежит вам, а процесс 12606 жив и принадлежит вам.

$ ./kill 1 $$ 123
process.Signal on pid 1 returned: operation not permitted
process.Signal on pid 12606 returned: <nil>
process.Signal on pid 123 returned: no such process

Ответ 2

В unix-подобных системах (linux, freebsd и т.д.) os.FindProcess никогда не вернет ошибку. Я не знаю, что происходит в Windows. Это означает, что вы не будете знать, правильно ли PID, пока вы не попытаетесь использовать * os.Process для чего-то.

Вы можете посмотреть код здесь.

Ответ 3

Вы также можете использовать syscall.Kill. Это меньше кода.

killErr := syscall.Kill(pid, syscall.Signal(0))
procExists := killErr == nil

Ответ 4

Если ранее неизвестный pid не найден в системе (не уверен в функциях go), это означает, что процесс определенно завершен и был присоединен (в Unix, wait call).

Но другой путь не обязательно верен. Просто потому, что pid существует, он не гарантирует, что это тот же процесс, что и раньше. Например, есть только 65535 действительных разрядов в стандартном Linux, и они могут быть повторно использованы, когда есть обертка. Однако, если вы достаточно часто проверяете, для практических целей вам не нужно заботиться об этом (до тех пор, пока pid неправильного нового процесса будет обнаружен не является уязвимостью безопасности или чем-то еще критическим, что кто-то может попытаться вызвать намеренно для вредоносных цели).

Ссылки по теме (и связанные вопросы в их соответствующих столбцах):

Ответ 5

В Windows проверка результата os.FindProcess() кажется достаточной, чтобы проверить, запущен ли процесс.

func isProcessRunning(pid int) bool {
    _, err = os.FindProcess(pid)
    if err != nil {
        return false
    }
    if runtime.GOOS == "windows" {
        return true
    }
    return false // further checking for other systems then Windows is not supported here
}