문제

IM은 다음과 같은 웹 앱에서 오랫동안 실행되는 스크립트를 생성합니다.

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

스크립트는 성공적으로 생성되고 실행되지만,이를 넘기기 전까지는 웹 앱에서 사용되는 포트, 즉 웹 앱을 다시 시작할 수 없습니다. 프로세스를 스폰하고 웹 앱과 완전히 독립적으로 만들려면 어떻게해야합니까?

이것은 Linux OS에 있습니다.

도움이 되었습니까?

해결책

@mark가 Linux 시스템이라고 설명하면서 스크립트는 쉽게 완전히 독립적으로 만들 수 있습니다. 악마, 이것을 따르면 레시피. (당신은 또한 부모에게서 그것을 할 수 있습니다. os.fork 그리고 그때에야 os.exec... 아동 과정).

편집 : 일부 세부 사항을 명확히하기 위해 내 답변에 대한 WRT @Mark의 의견 : Cookbook 레시피에 따라 프로세스를 "데모어"하는 데 슈퍼 사용자 권한이 필요하지 않으며 현재 작업 디렉토리를 변경할 필요가 없습니다 (의 코드는 있지만 현재 코드가 필요하지 않습니다. 레시피는 그렇게하는 것과 그 이상을 수행합니다. 그것은 중요한 부분이 아닙니다. 오히려 그것은 적절한 논리 시퀀스입니다. fork, _exit 그리고 setsid 전화). 다양한 os.exec... 하는 변형 ~ 아니다 끝납니다 e 부모 프로세스의 환경을 사용하여 부분적으로 쉽게 파이썬 온라인 문서.

다른 사람들의 의견과 답변에서 이루어진 제안을 다루기 위해 : 나는 믿습니다. subprocess 그리고 multiprocessing 그 자체는 아동 프로세스를 데모하지 않는다. 이것은 @mark가 필요로하는 것 같다. 스크립트는 스스로 할 수 있지만 그 이후로 약간 코드는 수행해야합니다 fork모래 setsid, 운영 과정에서 높은 수준과 낮은 수준의 코드를 혼합하지 않고 저수면 평면에서 모든 산란을 유지하는 것이 나에게 깔끔한 것 같습니다.

다음은 상기 URL에서 레시피의 크게 줄어들고 단순화 된 버전이 있습니다. 부모가 데몬 하위를 생성하도록 호출되도록 조정되었습니다.이 방법으로 코드는 비 파이썬 실행 파이브를 실행하는 데 사용될 수 있습니다. 주어진대로, 코드는 @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