即时消息传产生的脚本,该脚本从这样的Web应用程序中运行很长时间:

os.spawnle(os.P_NOWAIT, "../bin/producenotify.py", "producenotify.py", "xx",os.environ)

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

这是在Linux OS上。

有帮助吗?

解决方案

正如@mark澄清的那样是一个Linux系统,该脚本很容易使自己完全独立,即 守护程序, ,通过此操作 食谱. 。 (您也可以在父母之后在父母中进行 os.fork 直到那时 os.exec... 儿童过程)。

编辑:为了澄清一些详细信息WRT @Mark对我的答案的评论:不需要按照食谱食谱的配方来“守护”过程,也不需要更改当前的工作目录(尽管代码中的代码中的代码食谱确实做到了,而且这不是关键部分 - 而是正确的逻辑顺序 fork, _exitsetsid 电话)。各种种类 os.exec... 做的变体 不是 结束 e 使用父过程的环境,因此该部分也很容易 - 请参阅 Python在线文档.

解决他人的评论和答案中提出的建议:我相信 subprocessmultiprocessing 本身不要避免孩子的过程,这似乎是@mark所需的;脚本可以自己做,但是 一些 代码必须做 forksetsid, ,对我来说,将所有产卵放在那个低级平面上,而不是在操作过程中混合一些高级和一些低级代码,这对我来说似乎是更无所求的。

这是上面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)

其他提示

您可以使用多处理库来产生流程。这里显示了一个基本示例:

from multiprocessing import Process

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

if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()
    p.join()
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top