给出其pid,检查进程是否存在

Sim*_*one 37 c linux pid

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

Bla*_*iev 73

发出kill(2)系统调用0作为信号.如果调用成功,则表示存在具有此pid的进程.

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

引用POSIX标准:

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

请注意,您在竞争条件下不安全:目标进程可能已退出,同时已启动具有相同pid的另一个进程.或者,在您检查过程后,该过程可能会很快退出,您可以根据过时的信息做出决定.

只有当给定的pid是子进程(fork从当前进程编辑)时,您才可以使用waitpid(2)WNOHANG选项,或尝试捕获SIGCHLD信号.这些在竞争条件下是安全的,但仅与子进程相关.

  • 当且仅当您正在测试的进程是您自己的子进程时,`kill`方法是安全的.在这种情况下,进程ID属于您,并且在您等待它之前不能重复使用.否则,**任何使用**的pid都是一个严重的错误. (14认同)
  • 呼叫成功并不意味着该过程存在.这意味着*某些*进程存在于该PID中,这可能是也可能不是他想要了解的过程. (6认同)
  • @MarvinEffing 我知道这是一个旧的回复,但如果它对其他人有帮助,你必须检查“errno”。如果出现错误,`kill()` 的返回码将为 -1。答案和[文档](http://man7.org/linux/man-pages/man2/kill.2.html)中都指出了这一点。 (2认同)

Jan*_*sen 15

使用procfs.

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

轻松携带

  • 的Solaris
  • IRIX
  • Tru64 UNIX
  • BSD
  • Linux的
  • IBM AIX
  • QNX
  • 贝尔实验室的9号计划


the*_*aul 12

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

(getpgid(pid) >= 0)
Run Code Online (Sandbox Code Playgroud)

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

  • @tianyapiaozi我怀疑如果是这种情况,进程已经_exited_但尚未_reaped_(进程记录仍然处于“僵尸”状态,直到父进程检查它以获取其返回值)。不过,你是对的,如果一个进程“存在”,这里并没有严格定义它的含义。至少我很有信心,如果这个表达式返回 true,那么 `kill(pid, 0)` 也会返回 true。 (2认同)