【问题标题】:How to tell process id within Python如何在 Python 中判断进程 ID
【发布时间】:2010-05-21 18:49:50
【问题描述】:

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

mosrun ls &

这样自然会创建进程并在后台运行,返回进程id,像这样:

[1] 29199

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

编辑

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

谢谢

【问题讨论】:

  • 通常子进程会在父进程死亡时继续运行。

标签: python process mosix


【解决方案1】:

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

【讨论】:

  • 优秀 - 也在寻找这个
  • 这不是说我的新进程将是python进程的子进程吗?当我终止 python 进程时会发生什么? (见编辑)。谢谢
【解决方案2】:

看起来你想确保子进程是daemonized -- 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!-) 中的那些函数来完成后者是一件好事的原因!-)

【讨论】:

  • 谢谢。我能否从旧进程中知道守护进程的进程 ID?
  • 双叉子有点碍事,所以你需要沟通它——例如,子进程可能会将孙子进程的进程id写入它的stdout(父进程可以在它被分叉之后和它终止之前从) 中获取它。不过,您需要为此制定自己的协议,因为标准 Python 库中没有既定协议。
【解决方案3】:

感谢大家的帮助。这是我最后所做的,似乎工作正常。代码使用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-12-05
    • 2013-05-10
    • 1970-01-01
    • 2010-10-22
    • 2012-07-31
    • 2013-10-02
    • 1970-01-01
    • 2017-06-22
    • 2011-04-20
    相关资源
    最近更新 更多