如何在Python中获取进程ID

7 投票
3 回答
1830 浏览
提问于 2025-04-15 23:00

我正在使用一个基于Linux的集群系统(网址:www.mosix.org),这个系统可以让我在不同的电脑上运行任务。任务的运行方式如下:

mosrun ls &

这样做会在后台创建一个进程,并返回这个进程的ID,像这样:

[1] 29199

之后它会返回结果。我正在写一个Python程序,用来运行和控制这些任务。为了实现这个目标,我想像上面那样使用mosrun程序来运行任务,并保存新创建的进程的ID(在这个例子中是29199)。这显然不能通过os.system或commands.getoutput来完成,因为打印出来的ID并不是进程输出的内容……有没有什么建议?

补充说明

因为这个Python脚本只是用来最初运行任务,所以这些任务需要运行的时间比Python脚本本身要长。我想这意味着mosrun进程不能是这个脚本的子进程。有什么建议吗?

谢谢

3 个回答

0

感谢大家的帮助。最后我做了这些,看起来效果还不错。这个代码使用了 python-daemon。也许在把子进程的ID传给父进程时,可以做得更聪明一些,但这部分相对简单。

import daemon
def run_in_background(command, tmp_dir="/tmp"):

    # Decide on a temp file beforehand
    warnings.filterwarnings("ignore", "tempnam is a potential security")
    tmp_filename = os.tempnam(tmp_dir)

    # Duplicate the process
    pid = os.fork()


    # If we're child, daemonize and run
    if pid == 0:
        with daemon.DaemonContext():
            child_id = os.getpid()
            file(tmp_filename,'w').write(str(child_id))
            sp = command.split(' ')
            os.execl(*([sp[0]]+sp))
    else:
        # If we're a parent, poll for the new file
        n_iter = 0
        while True:
            if os.path.exists(tmp_filename):
                child_id = int(file(tmp_filename, 'r').read().strip())
                break

            if n_iter == 100:
                raise Exception("Cannot read process id from temp file %s" % tmp_filename)
            n_iter += 1

            time.sleep(0.1)

        return child_id
3

可以使用 subprocess 这个模块。通过这个模块创建的 Popen 实例有一个叫 pid 的属性。

2

看起来你想确保子进程是守护进程。PEP 3143文档中有关于这个的说明,并且提供了一些参考实现。

一旦你的进程(仍在运行Python代码)被设置为守护进程,不管是通过PEP 3143提供的方法还是其他方式,你可以使用os.execl(或者其他的os.exec...函数)来运行你的目标代码——这会在我们刚刚提到的那个守护进程中运行目标代码,因此它会保持守护进程的状态,正如你所希望的那样。

最后一步不能使用subprocess,因为它需要在同一个(守护进程)中运行,覆盖其可执行代码——这正是os.execl和其他相关函数的用途。

在守护进程化之前的第一步,理论上可以通过subprocess来完成,但这样做有点麻烦(你需要把守护进程化和os.exec的代码放在一个单独的.py文件中):通常你会想要直接使用os.fork,然后立即将子进程设置为守护进程。

subprocess是一个相当方便的跨平台方式来运行其他进程,但在一些高级用法(比如守护进程化)上,它并不能完全替代Unix的“fork和exec”方法——这就是为什么Python标准库也提供了通过os模块中的那些函数来实现这一点的好处!

撰写回答