【问题标题】:Check if process exists given its pid检查进程是否存在给定它的 pid
【发布时间】:2012-02-27 12:10:01
【问题描述】:

鉴于 Linux 进程的 pid,我想从 C 程序检查该进程是否仍在运行。

【问题讨论】:

标签: c linux pid


【解决方案1】:

使用0 作为信号发出kill(2) 系统调用。如果调用成功,说明存在这个pid的进程。

如果调用失败且errno 设置为ESRCH,则不存在具有此类 pid 的进程。

引用 POSIX 标准:

如果 sig 为 0(空信号),则执行错误检查,但不执行 实际发送信号。空信号可用于检查 pid的有效性。

请注意,您无法避免竞争条件:目标进程可能已退出,同时具有相同 pid 的另一个进程已启动。或者你检查后进程可能很快退出,你可以根据过时的信息做出决定。

仅当给定的 pid 属于子进程(fork'ed 来自当前进程)时,您可以使用 waitpid(2)WNOHANG 选项,或尝试捕获 SIGCHLD 信号。这些在竞争条件下是安全的,但仅与子进程相关。

【讨论】:

  • 调用成功不代表进程存在。这意味着 一些 进程存在具有该 PID,这可能是也可能不是他想知道的进程。
  • kill 方法是安全的当且仅当您正在测试的进程是您自己的子进程。在这种情况下,进程 id 属于您,在您为它wait 之前不能重复使用。否则,任何使用 pid 都是一个严重的错误。
  • 按照您的示例并从 kill() 的手册页中得到返回值 -1 而不是预期的 ESRCH。有什么我做错了吗? perror()No such process
  • @MarvinEffing 我知道这是一个旧回复,但如果它对其他人有帮助,您必须检查errno。如果出现错误,kill() 的返回码将为 -1。这在答案和documentation中都有指出。
【解决方案2】:

使用procfs。

#include <sys/stat.h>
[...]
struct stat sts;
if (stat("/proc/<pid>", &sts) == -1 && errno == ENOENT) {
  // process doesn't exist
}

便于携带

  • 索拉里斯
  • IRIX
  • Tru64 UNIX
  • BSD
  • Linux
  • IBM AIX
  • QNX
  • 贝尔实验室的计划 9

【讨论】:

    【解决方案3】:

    kill(pid, 0) 是典型的方法,正如@blagovest-buyukliev 所说。但是如果您正在检查的进程可能由不同的用户拥有,并且您不想采取额外的步骤来检查是否errno == ESRCH,那么事实证明

    (getpgid(pid) >= 0)
    

    是一种确定任何进程是否具有给定 PID 的有效一步法(因为即使对于不属于您的进程,您也可以检查进程组 ID)。

    【讨论】:

    • 有时进程退出但 getpgid(pid) 仍然返回正值。
    • @tianyapiaozi 我怀疑如果是这样的话,进程已经exited但是还没有reaped(进程记录还存在于一个“僵尸”状态,直到父进程检查它以获得它的返回值)。但是,您是对的,如果进程“存在”,则没有严格定义此处的含义。至少我很有信心,如果这个表达式返回 true,那么 kill(pid, 0) 也会。
    【解决方案4】:

    您可以使用0 作为信号发出kill(2) 系统调用。

    kill -0 没有什么不安全的地方。该程序 必须意识到结果可能随时过时 (包括 pid 可以在 kill 被调用之前被重用), 就这样。而使用 procfs 确实 也使用 pid, 并且以更繁琐和非标准的方式这样做。

    【讨论】:

      【解决方案5】:

      作为 /proc 文件系统方法的附录,您可以检查 /proc//cmdline(假设它是从命令行启动的)以查看它是否是您想要的进程。

      【讨论】:

      • commandline 有两种含义——一种(/proc//cmdline 中的那个)是“程序运行的名称,带有传递给它的参数列表”)适用于每个进程,即使不是从“命令行”启动(不同的含义:一个基于文本的界面,以造福人类)。
      【解决方案6】:
      ps -p $PID > /dev/null 2>&1;   echo $?
      

      如果带有$PID 的进程仍在运行,则此命令返回0。否则返回1

      也可以在 OSX 终端中使用此命令。

      【讨论】:

      • 这不能回答问题(“...来自 C 程序”),并且与kill 方法存在相同的竞争条件。
      猜你喜欢
      • 2010-10-08
      • 2011-03-03
      • 2011-06-06
      • 1970-01-01
      • 1970-01-01
      • 2014-03-06
      • 2011-07-09
      • 2016-10-17
      相关资源
      最近更新 更多