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?
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With