views:

1813

answers:

3

Is there a way to check to see if a pid corrosponds to a valid process? I'm getting a pid from a different source other than from os.getpid() and I need to check to see if a process with that pid doesn't exist on the machine. Much thanks.

Update: I need it to be available in Unix and Windows.

Update #2: I should be more specific - I'm checking to see if the PID is NOT in use.

+11  A: 

Sending signal 0 to a pid will raise an OSError exception if the pid is not running, and do nothing otherwise.

import os
import signal

def check_pid(pid):        
    """ Check For the existence of a unix pid. """
    try:
        os.kill(pid, 0)
    except OSError:
        return False
    else:
        return True
mluebke
Does this only work on unix-based machines?
Evan Fosmark
Also, doesn't this kill the process?
Evan Fosmark
Works for sure in linux and OSX, I can't speak for Windows. It does not kill the process in the sense that you are asking, it sends signal 0, which is basically "Are you running?".
mluebke
Ah, I see. Thanks for the code, but what I really need is something that runs in Windows as well.
Evan Fosmark
Why SIG_DFL? Signal 0 has no name, and should (to my knowledge) be written as 0, not as SIG_DFL (which does not have a mandated value, and can stand for some other value on other systems).
Chris Jester-Young
In the python signal module, signal 0 is defined as SIG_DFL. Unless I am misinterpreting the module.
mluebke
This definitely doesn't work on Windows, as there's no such thing as UNIX-like signals.
Alex Lebedev
To be complete, you should also check for the error number to make sure it is 3 (catch the exception and check for first arg). This is important if the target process exists but you don't have permission to send signal (for whatever reason).
haridsv
+1  A: 

Look here for windows-specific way of getting full list of running processes with their IDs. It would be something like

from win32com.client import GetObject
def get_proclist():
    WMI = GetObject('winmgmts:')
    processes = WMI.InstancesOf('Win32_Process')
    return [process.Properties_('ProcessID').Value for process in processes]

You can then verify pid you get against this list. I have no idea about performance cost, so you'd better check this if you're going to do pid verification often.

For *NIx, just use mluebke's solution.

Alex Lebedev
+1  A: 

I'd say use the PID for whatever purpose you're obtaining it and handle the errors gracefully. Otherwise, it's a classic race (the PID may be valid when you check it's valid, but go away an instant later)

Damien_The_Unbeliever
I should have been more specific - I'm checking for the INVALIDITY. So, I basically want to be able to see if a pid is NOT in use.
Evan Fosmark
But what will you do with that answer? The instant after you've gained that knowledge, something might use that pid.
Damien_The_Unbeliever
@Damien_The_Unbeliever - that's alright if something is using it after I gain that knowledge, and I understand what you're saying about the race condition, but I can assure you that it doesn't apply for my situation.
Evan Fosmark