Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Opening a process with Popen and getting the PID

I'm working on a nifty little function:

def startProcess(name, path):     """     Starts a process in the background and writes a PID file      returns integer: pid     """      # Check if the process is already running     status, pid = processStatus(name)      if status == RUNNING:         raise AlreadyStartedError(pid)      # Start process     process = subprocess.Popen(path + ' > /dev/null 2> /dev/null &', shell=True)      # Write PID file     pidfilename = os.path.join(PIDPATH, name + '.pid')     pidfile = open(pidfilename, 'w')     pidfile.write(str(process.pid))     pidfile.close()      return process.pid 

The problem is that process.pid isn't the correct PID. It seems it's always 1 lower than the correct PID. For instance, it says the process started at 31729, but ps says it's running at 31730. Every time I've tried it's off by 1. I'm guessing the PID it returns is the PID of the current process, not the started one, and the new process gets the 'next' pid which is 1 higher. If this is the case, I can't just rely on returning process.pid + 1 since I have no guarantee that it'll always be correct.

Why doesn't process.pid return the PID of the new process, and how can I achieve the behaviour I'm after?

like image 447
Hubro Avatar asked Nov 03 '11 03:11

Hubro


People also ask

Does Popen wait for process to finish?

A Popen object has a . wait() method exactly defined for this: to wait for the completion of a given subprocess (and, besides, for retuning its exit status). If you use this method, you'll prevent that the process zombies are lying around for too long. (Alternatively, you can use subprocess.

Does Popen need to be closed?

Popen do we need to close the connection or subprocess automatically closes the connection? Usually, the examples in the official documentation are complete. There the connection is not closed. So you do not need to close most probably.


1 Answers

From the documentation at http://docs.python.org/library/subprocess.html:

Popen.pid The process ID of the child process.

Note that if you set the shell argument to True, this is the process ID of the spawned shell.

If shell is false, it should behave as you expect, I think.

If you were relying on shell being True for resolving executable paths using the PATH environment variable, you can accomplish the same thing using shutil.which instead, then pass the absolute path to Popen instead. (As an aside, if you are using Python 3.5 or newer, you should be using subprocess.run rather than Popen.

like image 104
krousey Avatar answered Sep 29 '22 10:09

krousey