【问题标题】:python how to run process in detached modepython如何以分离模式运行进程
【发布时间】:2018-08-13 20:59:07
【问题描述】:

这是一个例子:

from multiprocessing import Process
import time


def func():
    print('sub process is running')
    time.sleep(5)
    print('sub process finished')


if __name__ == '__main__':
    p = Process(target=func)
    p.start()
    print('done')

我希望主进程在启动子进程后立即终止。但是在打印出“完成”后,终端仍在等待......有没有办法做到这一点,以便主进程在打印出“完成”后立即退出,而不是等待子进程?我在这里很困惑,因为我没有打电话给p.join()

【问题讨论】:

    标签: python multiprocessing


    【解决方案1】:

    如果存在非daemon process,Python 不会结束。

    通过在start()调用之前设置daemon属性,可以使进程成为守护进程。

    p = Process(target=func)
    p.daemon = True  # <-----
    p.start()
    print('done')
    

    注意:不会打印sub process finished 消息;因为主进程将在退出时终止子进程。这可能不是你想要的。

    你应该做双叉:

    import os
    import time
    from multiprocessing import Process
    
    
    def func():
        if os.fork() != 0:  # <--
            return          # <--
        print('sub process is running')
        time.sleep(5)
        print('sub process finished')
    
    
    if __name__ == '__main__':
        p = Process(target=func)
        p.start()
        p.join()
        print('done')
    

    【讨论】:

    • 喜欢这种方法!但我听说使用 os.fork 有一些顾虑。这个用例会带来任何风险吗?
    • @NolanConaway, man 2 fork :) 如果可能,请尽早分叉以避免不必要的资源复制。如果叉前有锁,则应小心处理。 ....
    • 同样相关,3.7 中的新功能docs.python.org/3/library/os.html#os.register_at_fork
    【解决方案2】:

    根据@falsetru 的出色回答,我以装饰器的形式写了一个快速概括。

    import os
    from multiprocessing import Process
    
    
    def detachify(func):
        """Decorate a function so that its calls are async in a detached process.
    
        Usage
        -----
    
        .. code::
                import time
    
                @detachify
                def f(message):
                    time.sleep(5)
                    print(message)
    
                f('Async and detached!!!')
    
        """
        # create a process fork and run the function
        def forkify(*args, **kwargs):
            if os.fork() != 0:
                return
            func(*args, **kwargs)
    
        # wrapper to run the forkified function
        def wrapper(*args, **kwargs):
            proc = Process(target=lambda: forkify(*args, **kwargs))
            proc.start()
            proc.join()
            return
    
        return wrapper
    

    用法(从文档字符串复制):

    import time
    
    @detachify
    def f(message):
        time.sleep(5)
        print(message)
    
    f('Async and detached!!!')
    

    如果你喜欢,

    def f(message):
        time.sleep(5)
        print(message)
    
    
    detachify(f)('Async and detached!!!')
    

    【讨论】:

    • 更新:在 python 2.7、3.5、3.6、3.7 上测试并运行
    • 这看起来很有用。虽然我没有测试过。这会创建一个新的父进程还是子进程?我正在尝试找到一种方法来创建一个全新的进程,以便我可以关闭调用此进程的终端。
    • 确实可以创建进程退出终端!
    猜你喜欢
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-29
    相关资源
    最近更新 更多