문제
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()