我试图打开一个子进程,但希望它与调用它的父脚本分离。现在,如果我调用subprocess.popen并且父脚本崩溃,子进程也会死亡。
我知道windows有几个选项,但我没有找到*nix的任何东西。
我也不需要使用subprocess来调用这个进程。我只需要能够调用另一个进程并获取pid即可。
我知道windows有几个选项,但我没有找到*nix的任何东西。
我也不需要使用subprocess来调用这个进程。我只需要能够调用另一个进程并获取pid即可。
使用Linux操作系统,这个问题不成问题。只需要使用Popen()
函数即可。举个例子,下面是一个小小的dying_demon.py
示例:
#!/usr/bin/python -u
from time import sleep
from subprocess import Popen
print Popen(["python", "-u", "child.py"]).pid
i = 0
while True:
i += 1
print "demon: %d" % i
sleep(1)
if i == 3:
i = hurz # exception
child.py
。#!/usr/bin/python -u
from time import sleep
i = 0
while True:
i += 1
print "child: %d" % i
sleep(1)
if i == 20:
break
detach_process=True
。def cmd_detach(*command, **kwargs) -> subprocess.CompletedProcess:
# https://dev59.com/HLvoa4cB1Zd3GeqP98TP
# if using with ffmpeg remember to run it with `-nostdin`
stdout = os.open(os.devnull, os.O_WRONLY)
stderr = os.open(os.devnull, os.O_WRONLY)
stdin = os.open(os.devnull, os.O_RDONLY)
command = conform(command)
if command[0] in ["fish", "bash"]:
import shlex
command = command[0:2] + [shlex.join(command[2:])]
subprocess.Popen(command, stdin=stdin, stdout=stdout, stderr=stderr, close_fds=True, start_new_session=True, **kwargs)
return subprocess.CompletedProcess(command, 0, "Detached command is async")
在Windows上,您可能需要
CREATE_NEW_PROCESS_GROUP = 0x00000200
DETACHED_PROCESS = 0x00000008
creationflags=DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP
替换为start_new_session=True
。
使用NOHUP选项fork子进程
shell=True
,那么这个方法是行不通的,但如果没有必要的话,这会增加负担。 - Nick T我使用python-daemon进行了以下操作,成功让它工作:
process = subprocess.Popen(["python", "-u", "Child.py"])
time.sleep(2)
process.kill()
然后在Child.py中:
with daemon.DaemonContext():
print("Child Started")
time.sleep(30)
print "Done"
exit()
我使用process.kill()
来结束进程,否则会创建一个僵尸Python进程。现在我遇到的主要问题是,popen返回的PID与最终进程的PID不匹配。我可以通过在Child.py中添加一个函数来更新数据库中的PID来解决这个问题。
如果我漏掉了什么或者这种方法可行,请告诉我。
os._exit()
...(在链接答案中的活动状态食谱中检查PID),请参阅http://code.activestate.com/recipes/278731-creating-a-daemon-the-python-way/。 - Joran Beasley