【问题标题】:Deliberately make an orphan process in python故意在python中创建一个孤儿进程
【发布时间】:2012-10-17 05:56:26
【问题描述】:

我有一个名为 MyScript 的 Python 脚本(类 unix,基于 RHEL),它有两个函数,分别称为 A 和 B。我希望它们在不同的独立进程中运行(分离 B 和 A):

  • 启动脚本 MyScript
  • 执行函数A
  • 产生一个新进程,将数据从函数 A 传递到 B
  • 当函数 B 运行时,继续函数 A
  • 当函数 A 完成时,即使 B 仍在运行,也要退出 MyScript

我认为我应该使用多处理来创建一个守护进程,但documentation 表明这不是正确的用例。所以,我决定生成一个子进程和 child^2 进程(孩子的孩子),然后强制孩子终止。虽然这种解决方法似乎有效,但看起来真的很难看。

你能帮我让它更 Pythonic 吗? subprocess 模块是否有对函数进行操作的方法?示例代码如下。

import multiprocessing
import time
import sys
import os

def parent_child():
    p = multiprocessing.current_process()
    print 'Starting parent child:', p.name, p.pid
    sys.stdout.flush()
    cc = multiprocessing.Process(name='childchild', target=child_child)
    cc.daemon = False
    cc.start()
    print 'Exiting parent child:', p.name, p.pid
    sys.stdout.flush()

def child_child():
    p = multiprocessing.current_process()
    print 'Starting child child:', p.name, p.pid
    sys.stdout.flush()
    time.sleep(30)
    print 'Exiting child child:', p.name, p.pid
    sys.stdout.flush()

def main():
    print 'starting main', os.getpid()
    d = multiprocessing.Process(name='parentchild', target=parent_child)
    d.daemon = False
    d.start()
    time.sleep(5)
    d.terminate()
    print 'exiting main', os.getpid()

main()

【问题讨论】:

  • @Keith,刚刚更新了问题。类 Unix。

标签: python parallel-processing python-2.7 subprocess multiprocessing


【解决方案1】:

这只是您原始代码的随机版本,它将功能移动到单个调用spawn_detached(callable)。即使在程序退出后,它也会保持分离的进程运行:

import time
import os
from multiprocessing import Process, current_process

def spawn_detached(callable):
    p = _spawn_detached(0, callable)
    # give the process a moment to set up
    # and then kill the first child to detach
    # the second.
    time.sleep(.001)
    p.terminate()

def _spawn_detached(count, callable):
    count += 1
    p = current_process()
    print 'Process #%d: %s (%d)' % (count, p.name, p.pid)

    if count < 2:
        name = 'child'
    elif count == 2:
        name = callable.func_name
    else:
        # we should now be inside of our detached process
        # so just call the function
        return callable()

    # otherwise, spawn another process, passing the counter as well
    p = Process(name=name, target=_spawn_detached, args=(count, callable)) 
    p.daemon = False 
    p.start()
    return p

def operation():
    """ Just some arbitrary function """
    print "Entered detached process"
    time.sleep(15)
    print "Exiting detached process"


if __name__ == "__main__":
    print 'starting main', os.getpid()
    p = spawn_detached(operation)
    print 'exiting main', os.getpid()

【讨论】:

  • 程序没有退出。尝试运行the code in my answer。它表明子进程(.daemon=False)在主线程退出时加入。或者您可以在 top 中查找 pid(用于您的代码)。
  • @J.F.Sebastian:我不确定你在说什么。程序立即退出到 shell,原来的 PID 不再存在。只有operation PID 存在。
  • 我被"The entire Python program exits when no alive non-daemon threads are left." 误导了,所以我决定守护线程不应该让进程保持活动状态。
  • @J.F.Sebastian:我正要问这个问题,因为我很难弄清楚你的示例显示什么来回答原始问题(因为主 PID 保持运行)。虽然我不得不说你比我有更多精心设计的信息,而且无论如何都是一个很好的例子。
  • 这个例子的目的是为了证明主进程没有退出。我错过了 OP(和你的)代码中的双叉。如果 OP 最终想要创建一个 Unix 守护进程,你应该提到 python-daemon 包。
猜你喜欢
  • 2020-06-04
  • 2020-09-09
  • 2014-12-06
  • 2017-01-18
  • 2014-01-08
  • 1970-01-01
  • 2011-10-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多