使用 Popen 打开进程并获取 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
问题在于 process.pid
不是正确的 PID.它似乎总是比正确的PID低1.例如,它说进程从 31729 开始,但 ps
说它在 31730 运行.每次我尝试它都会关闭 1.我猜它返回的 PID 是当前 进程,而不是启动的进程,并且新进程获得高 1 的下一个"pid.如果是这种情况,我不能仅仅依靠返回 process.pid + 1
因为我不能保证它总是正确的.
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.
process.pid
为什么不返回新进程的PID,如何实现我想要的行为?
Why doesn't process.pid
return the PID of the new process, and how can I achieve the behaviour I'm after?
解决方案
来自 http://docs.python.org/library/subprocess.html:
Popen.pid 子进程的进程ID.
Popen.pid The process ID of the child process.
注意,如果你将shell参数设置为True,这就是进程生成的 shell 的 ID.
Note that if you set the shell argument to True, this is the process ID of the spawned shell.
如果 shell
为假,我认为它的行为应该如您所愿.
If shell
is false, it should behave as you expect, I think.
如果您依赖 shell
是 True
来使用 PATH
环境变量解析可执行路径,则可以使用 shutil.which
代替,然后通过而是 Popen 的绝对路径.(顺便说一句,如果您使用的是 Python 3.5 或更高版本,则应该使用 subprocess.run
而不是 Popen.
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.
相关文章