【发布时间】:2012-02-27 12:10:01
【问题描述】:
鉴于 Linux 进程的 pid,我想从 C 程序检查该进程是否仍在运行。
【问题讨论】:
-
你可能想看看这个:stackoverflow.com/questions/939778/…
鉴于 Linux 进程的 pid,我想从 C 程序检查该进程是否仍在运行。
【问题讨论】:
使用0 作为信号发出kill(2) 系统调用。如果调用成功,说明存在这个pid的进程。
如果调用失败且errno 设置为ESRCH,则不存在具有此类 pid 的进程。
引用 POSIX 标准:
如果 sig 为 0(空信号),则执行错误检查,但不执行 实际发送信号。空信号可用于检查 pid的有效性。
请注意,您无法避免竞争条件:目标进程可能已退出,同时具有相同 pid 的另一个进程已启动。或者你检查后进程可能很快退出,你可以根据过时的信息做出决定。
仅当给定的 pid 属于子进程(fork'ed 来自当前进程)时,您可以使用 waitpid(2) 和 WNOHANG 选项,或尝试捕获 SIGCHLD 信号。这些在竞争条件下是安全的,但仅与子进程相关。
【讨论】:
kill 方法是安全的当且仅当您正在测试的进程是您自己的子进程。在这种情况下,进程 id 属于您,在您为它wait 之前不能重复使用。否则,任何使用 pid 都是一个严重的错误。
kill() 的手册页中得到返回值 -1 而不是预期的 ESRCH。有什么我做错了吗? perror() 给No such process。
errno。如果出现错误,kill() 的返回码将为 -1。这在答案和documentation中都有指出。
使用procfs。
#include <sys/stat.h>
[...]
struct stat sts;
if (stat("/proc/<pid>", &sts) == -1 && errno == ENOENT) {
// process doesn't exist
}
便于携带
【讨论】:
kill(pid, 0) 是典型的方法,正如@blagovest-buyukliev 所说。但是如果您正在检查的进程可能由不同的用户拥有,并且您不想采取额外的步骤来检查是否errno == ESRCH,那么事实证明
(getpgid(pid) >= 0)
是一种确定任何进程是否具有给定 PID 的有效一步法(因为即使对于不属于您的进程,您也可以检查进程组 ID)。
【讨论】:
kill(pid, 0) 也会。
您可以使用0 作为信号发出kill(2) 系统调用。
kill -0 没有什么不安全的地方。该程序
必须意识到结果可能随时过时
(包括 pid 可以在 kill 被调用之前被重用),
就这样。而使用 procfs 确实 也使用 pid,
并且以更繁琐和非标准的方式这样做。
【讨论】:
作为 /proc 文件系统方法的附录,您可以检查 /proc/
【讨论】:
ps -p $PID > /dev/null 2>&1; echo $?
如果带有$PID 的进程仍在运行,则此命令返回0。否则返回1。
也可以在 OSX 终端中使用此命令。
【讨论】:
kill 方法存在相同的竞争条件。