使用Popen打开进程并获取PID

61 投票
1 回答
131736 浏览
提问于 2025-04-17 05:32

我正在做一个很有意思的小功能:

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 返回的进程ID(PID)不对。它似乎总是比正确的PID少1。例如,它显示进程在31729启动,但用ps命令查看时显示它在31730运行。每次我尝试的时候,都是差1。我猜process.pid返回的是当前进程的PID,而不是刚启动的那个新进程的PID,而新进程会得到下一个PID,也就是比当前PID大1。如果真是这样,我不能仅仅依赖返回process.pid + 1,因为我不能保证这样总是正确。

为什么process.pid不返回新进程的PID,我该如何实现我想要的效果呢?

1 个回答

56

根据文档内容,来自 http://docs.python.org/library/subprocess.html

Popen.pid 是子进程的进程 ID。

注意,如果你把 shell 参数设置为 True,那么这个就是新启动的 shell 的进程 ID。

如果 shell 设置为 false,应该会按照你的预期工作,我觉得。

如果你之前依赖 shellTrue 来通过 PATH 环境变量找到可执行文件的路径,你可以用 shutil.which 来实现同样的功能,然后把绝对路径传给 Popen。顺便提一下,如果你使用的是 Python 3.5 或更新的版本,建议使用 subprocess.run,而不是 Popen。

撰写回答