7

我正在使用 linux (www.mosix.org) 上的集群系统,它允许我运行作业并让系统在不同的计算机上运行它们。作业是这样运行的:

mosrun ls &

这自然会创建进程并在后台运行它,返回进程 ID,如下所示:

[1] 29199

稍后它会返回。我正在编写一个 Python 基础设施来运行作业并控制它们。为此,我想使用上述 mosrun 程序运行作业,并保存生成进程的进程 ID(在本例中为 29199)。这自然不能使用 os.system 或 commands.getoutput 来完成,因为打印的 ID 不是进程打印输出的内容......有什么线索吗?

编辑

由于 python 脚本仅用于初始运行脚本,因此脚本需要比 python shell 运行更长的时间。我想这意味着 mosrun 进程不能是脚本的子进程。有什么建议么?

谢谢

4

3 回答 3

3

使用subprocess模块。Popen实例有一个pid属性。

于 2010-05-21T18:53:52.690 回答
2

看起来您想确保子进程被守护进程——我指向的 PEP 3143 记录并指向了一个参考实现,并且也指向其他进程。

一旦您的进程(仍在运行 Python 代码)被守护,无论是通过 PEP 3143 或其他提供的方式,您都可以os.execl(或其他os.exec...函数)您的目标代码——这将在完全相同的进程中运行所述目标代码我们刚刚说过是守护进程,因此它会根据需要继续被守护进程。

最后一步无法使用subprocess,因为它需要在同一个(守护进程)进程中运行,覆盖其可执行代码——这正是os.execl和朋友们的目的。

可以想象,在守护进程之前的第一步可以通过 来完成subprocess,但这有点不方便(您需要将 daemonize-then-os.exec 代码放在一个单独的 中.py):最常见的是您只想os.fork立即守护子进程.

subprocess作为运行其他进程的主要跨平台方式非常方便,但它不能真正取代 Unix 用于高级用途(例如守护进程)的老式“fork and exec”方法——这就是它的原因Python 标准库还允许您通过模块中的那些函数执行后者,这是一件好事os!-)

于 2010-05-22T15:22:53.330 回答
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
于 2010-05-25T13:40:33.623 回答