检查流程是否存在

Fat*_*lan 15 process go

如果我有一个进程的PID,os.FindProcess是否足以测试现有的进程?我的意思是,如果它返回err我可以假设它已终止(或被杀死)?

编辑:

我刚刚编写了一个包装函数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
}
Run Code Online (Sandbox Code Playgroud)

Nic*_*ood 30

这是传统的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.
Run Code Online (Sandbox Code Playgroud)

并翻译成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)
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

当你运行它时,你得到这个,显示进程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
Run Code Online (Sandbox Code Playgroud)

  • 同时,这对已成为僵尸且未被父进程收获的进程没有影响 (2认同)

Ste*_*erg 5

在类似unix的系统(linux,freebsd等)上,os.FindProcess永远不会返回错误.我不知道Windows上会发生什么.这意味着在尝试使用*os.Process之前,您将不知道PID是否正确.

你可以在这里查看代码.


Art*_*pek 5

您也可以只使用syscall.Kill. 这相当于更少的代码。

killErr := syscall.Kill(pid, syscall.Signal(0))
procExists := killErr == nil
Run Code Online (Sandbox Code Playgroud)

  • 除了[Nick Craig-Wood 的回答](http://stackoverflow.com/a/15210305/55504) 的注释,现有进程可以返回非零错误。您应该有一个更复杂的条件(也许`err == nil || err == syscall.EPERM`,也许更多)。 (3认同)