从python中产生进程

mar*_*ark 12 python process spawn

我产生一个脚本,从这样的Web应用程序运行很长一段时间:

os.spawnle(os.P_NOWAIT, "../bin/producenotify.py", "producenotify.py", "xx",os.environ)
Run Code Online (Sandbox Code Playgroud)

该脚本成功生成并运行,但直到它结束我无法释放Web应用程序使用的端口,或者换句话说,我无法重新启动Web应用程序.我如何产生一个过程并使其完全独立于Web应用程序?

这是在linux操作系统上.

Ale*_*lli 26

由于@mark澄清它是一个Linux系统,脚本可以通过遵循这个配方轻松地使自己完全独立,即守护进程.(您也可以在父进程之后执行此操作,然后才进行子进程).os.forkos.exec...

编辑:澄清@ mark对我的回答的评论的一些细节:根据cookbook配方"daemonize"一个进程不需要超级用户权限,也不需要更改当前的工作目录(尽管代码在配方并做多,这不是关键的部分-而它的正确的逻辑顺序fork,_exitsetsid调用).不会使用父进程的环境结束的各种os.exec...变体,因此该部分也很容易 - 请参阅Python在线文档.e

为了解决别人的评论和答案中提出的建议:我相信subprocess并且multiprocessing本身并没有守护儿童过程,这似乎是@mark所需要的; 脚本可以自己做,但由于一些代码必须做forks setsid,我觉得最好把所有的产生保存在那个低级平面而不是混合一些高级代码和一些低级代码操作过程.

以下是上述URL中配方的大大简化和简化版本,可以在父级中调用以生成守护程序子级 - 这样,代码也可以用于执行非Python可执行文件.如上所述,代码应满足@mark解释的需求,当然它可以通过多种方式进行定制 - 我强烈建议您阅读原始配方及其评论和讨论,以及它推荐的书籍,以获取更多信息.

import os
import sys

def spawnDaemon(path_to_executable, *args)
    """Spawn a completely detached subprocess (i.e., a daemon).

    E.g. for mark:
    spawnDaemon("../bin/producenotify.py", "producenotify.py", "xx")
    """
    # fork the first time (to make a non-session-leader child process)
    try:
        pid = os.fork()
    except OSError, e:
        raise RuntimeError("1st fork failed: %s [%d]" % (e.strerror, e.errno))
    if pid != 0:
        # parent (calling) process is all done
        return

    # detach from controlling terminal (to make child a session-leader)
    os.setsid()
    try:
        pid = os.fork()
    except OSError, e:
        raise RuntimeError("2nd fork failed: %s [%d]" % (e.strerror, e.errno))
        raise Exception, "%s [%d]" % (e.strerror, e.errno)
    if pid != 0:
        # child process is all done
        os._exit(0)

    # grandchild process now non-session-leader, detached from parent
    # grandchild process must now close all open files
    try:
        maxfd = os.sysconf("SC_OPEN_MAX")
    except (AttributeError, ValueError):
        maxfd = 1024

    for fd in range(maxfd):
        try:
           os.close(fd)
        except OSError: # ERROR, fd wasn't open to begin with (ignored)
           pass

    # redirect stdin, stdout and stderr to /dev/null
    os.open(os.devnull, os.O_RDWR)  # standard input (0)
    os.dup2(0, 1)
    os.dup2(0, 2)

    # and finally let's execute the executable for the daemon!
    try:
      os.execv(path_to_executable, args)
    except Exception, e:
      # oops, we're cut off from the world, let's just give up
      os._exit(255)
Run Code Online (Sandbox Code Playgroud)

  • 为什么你有两个连续的加薪声明?我一直认为第二个永远不会被执行. (2认同)

Dan*_*enc 12

您可以使用多处理库来生成进程.这里显示了一个基本示例:

from multiprocessing import Process

def f(name):
    print 'hello', name

if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()
    p.join()
Run Code Online (Sandbox Code Playgroud)

  • 这个问题是在子进程完成之前不能杀死主进程.谢谢! (6认同)
  • @CadentOrange"此外,这些不是Unix守护进程或服务,如果非守护进程已退出,它们将被终止(并且不会被连接)的正常进程." (文档)并不是说在这种情况下会杀死守护进程吗? (2认同)