如何从Python脚本启动一个进程(例如另一个Python脚本),以便" child"过程完全脱离了父母",所以父母可以a)继续快乐的方式而不等待孩子完成,b)可以终止而不终止子过程?
父:
import os
print "Parent started"
os.system("./child.py")
print "Parent finished"
儿童:
import time
print "Child started"
time.sleep(10)
print "Child finished"
运行parent.py
打印:
Parent started
Child started
Child finished
Parent finished
我想要它打印:
Parent started
Child started
Parent finished
(seconds later)
Child finished
答案 0 :(得分:9)
由于您提到os.system
,我认为值得一提的是您应该使用os.spawn*
模式P_NOWAIT
来实现“忘记”部分。
但是subprocess
模块提供了os.system
,os,spawn*
等的替换,因此您应该使用它来代替
import subprocess
p = subprocess.Popen("./child.py")
print "pid = ", p.pid
请参阅Replacing os.spawn with subprocess.Popen
正如我在评论中所解释的,进程parent.py
和child.py
仍在同一进程组中,因此终端会将信号(如Ctrl-C
)转发给前台中的所有进程进程组,以便Ctrl-C
时两者都会被杀死。因此,如果您不希望这样,您可以强制child.py
进入具有以下内容的新流程组:
#!/usr/bin/env python
import subprocess
import time
import os
p = subprocess.Popen("./child.py", preexec_fn=os.setsid)
print "pid = ", p.pid
time.sleep(30) # Ctrl-C at this point will not kill child.py
print "parent exit"
答案 1 :(得分:1)
使用<a href="/">Back to login</a>
可以将简单的装饰器编写为asyncio
@background
生产
import asyncio
import time
def background(f):
def wrapped(*args, **kwargs):
return asyncio.get_event_loop().run_in_executor(None, f, *args, *kwargs)
return wrapped
@background
def foo():
time.sleep(1)
print("foo() completed")
print("Hello")
foo()
print("I didn't wait for foo()")
答案 2 :(得分:0)
回答我自己的问题:我最终只是在@kevinsa建议的命令末尾使用os.system
&
。这允许在不终止子进程的情况下终止父进程。
这里有一些代码:
<强> child.py 强>
#!/usr/bin/python
import time
print "Child started"
time.sleep(10)
print "Child finished"
parent.py ,使用subprocess.Popen:
#!/usr/bin/python
import subprocess
import time
print "Parent started"
subprocess.Popen("./child.py")
print "(child started, sleeping)"
time.sleep(5)
print "Parent finished"
<强>输出:强>
$ ./parent.py
Parent started
(child started, sleeping)
Child started
^CTraceback (most recent call last):
Traceback (most recent call last):
File "./child.py", line 5, in <module>
File "./parent.py", line 13, in <module>
time.sleep(10)
time.sleep(5)
KeyboardInterrupt
KeyboardInterrupt
parent.py ,使用os.system和&amp;
#!/usr/bin/python
import os
import time
print "Parent started"
os.system("./child.py &")
print "(child started, sleeping)"
time.sleep(5)
print "Parent finished"
<强>输出:强>
$ ./parent.py
Parent started
(child started, sleeping)
Child started
^CTraceback (most recent call last):
File "./parent.py", line 12, in <module>
time.sleep(5)
KeyboardInterrupt
$ Child finished
请注意孩子如何生活在Ctrl-C之外。