53

Given the pid of a Linux process, I want to check, from a C program, if the process is still running.

Mat
  • 202,337
  • 40
  • 393
  • 406
Simone
  • 2,261
  • 2
  • 19
  • 27
  • You may want to look at this: http://stackoverflow.com/questions/939778/linux-api-to-list-running-processes – xtrem Feb 05 '12 at 21:07

6 Answers6

106

Issue a kill(2) system call with 0 as the signal. If the call succeeds, it means that a process with this pid exists.

If the call fails and errno is set to ESRCH, a process with such a pid does not exist.

Quoting the POSIX standard:

If sig is 0 (the null signal), error checking is performed but no signal is actually sent. The null signal can be used to check the validity of pid.

Note that you are not safe from race conditions: it is possible that the target process has exited and another process with the same pid has been started in the meantime. Or the process may exit very quickly after you check it, and you could do a decision based on outdated information.

Only if the given pid is of a child process (fork'ed from the current one), you can use waitpid(2) with the WNOHANG option, or try to catch SIGCHLD signals. These are safe from race conditions, but are only relevant to child processes.

Blagovest Buyukliev
  • 42,498
  • 14
  • 94
  • 130
  • 7
    The call succeeding does not mean that the process exists. It means *some* process exists with that PID, which may or may not be the process that he wanted to know about. – David Schwartz Feb 05 '12 at 21:27
  • 18
    The `kill` method is safe if and only if the process you're testing for is your own child process. In this case, the process id belongs to you and cannot be reused until you `wait` for it. Otherwise, **any use** of a pid is a serious bug. – R.. GitHub STOP HELPING ICE Feb 05 '12 at 23:15
  • After following your example and from the man page of `kill()` I get return value -1 instead of the expected ESRCH. Is there something I'm doing wrong? `perror()` gives `No such process`. – Marvin Effing Feb 13 '19 at 14:40
  • 1
    @MarvinEffing I know this is an old reply, but in case it helps someone else, you have to check `errno` instead. The return code of `kill()` will be -1 if there is an error. This is pointed in the answer and also in the [documentation](http://man7.org/linux/man-pages/man2/kill.2.html). – SRG Nov 03 '19 at 14:14
19

kill(pid, 0) is the typical approach, as @blagovest-buyukliev said. But if the process you are checking might be owned by a different user, and you don't want to take the extra steps to check whether errno == ESRCH, it turns out that

(getpgid(pid) >= 0)

is an effective one-step method for determining if any process has the given PID (since you are allowed to inspect the process group ID even for processes that don't belong to you).

the paul
  • 8,972
  • 1
  • 36
  • 53
  • Sometimes process exits but getpgid(pid) still returns positive value. – tianyapiaozi Jan 17 '19 at 03:00
  • 2
    @tianyapiaozi I suspect that if that is the case, the process has _exited_ but has not yet been _reaped_ (the process record still exists in a "zombie" state until the parent process checks on it to get its return value). You are right, though, it's not strictly defined what it means here if a process "exists". I'm pretty confident, at least, that if this expression returns true, then `kill(pid, 0)` will also. – the paul Jan 17 '19 at 19:38
  • 1
    the necessary header is `` – ph_0 Oct 04 '22 at 16:20
18

Use procfs.

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

Easily portable to

  • Solaris
  • IRIX
  • Tru64 UNIX
  • BSD
  • Linux
  • IBM AIX
  • QNX
  • Plan 9 from Bell Labs
Janus Troelsen
  • 20,267
  • 14
  • 135
  • 196
4

You can issue a kill(2) system call with 0 as the signal.

There's nothing unsafe about kill -0. The program must be aware that the result can become obsolete at any time (including that the pid can get reused before kill is called), that's all. And using procfs instead does use the pid too, and doing so in a more cumbersome and nonstandard way.

James
  • 24,676
  • 13
  • 84
  • 130
Hallvard
  • 57
  • 2
3

As an addendum to the /proc filesystem method, you can check the /proc/<pid>/cmdline (assuming it was started from the command line) to see if it is the process you want.

Kinthelt
  • 31
  • 1
  • 2
    commandline has two meanings - one (the one in /proc//cmdline) is "the name of the program run, with a list of arguments passed to it") applies to EVERY process, even if not launched from the "command line" (different meaning: a text-based interface for the benefit of human beings). – AMADANON Inc. Sep 23 '14 at 03:19
-3
ps -p $PID > /dev/null 2>&1;   echo $?

This command return 0 if process with $PID is still running. Otherwise it returns 1.

One can use this command in OSX terminal too.

J. Chomel
  • 8,193
  • 15
  • 41
  • 69
Anver Hisham
  • 111
  • 3
  • 1
    That doesn't answer the question ("*... from a C program*") and suffers from the same race conditions as the `kill` approach. – melpomene Sep 04 '16 at 17:43