subprocess.Popen
下python3.2+
Linux
的{{1}}启动新流程的这两个选项有何区别:
proc = subprocess.Popen(args, ..., preexec_fn=os.setsid) # 1
proc = subprocess.Popen(args, ..., start_new_session=True) # 2
我需要这个,因为我需要设置进程组ID,以便有可能立即杀死此进程及其所有子进程。如果进程运行时间超过某个阈值,则用于此情况:
try:
out, err = proc.communicate(timeout=time_max)
except subprocess.TimeoutExpired:
os.killpg(os.getpgid(proc.pid), signal.SIGTERM)
我使用两个选项(#1
& #2
)测试了我的代码,它们似乎对我都有效。
但我想知道这里最好的选择是什么 - preexec_fn
或start_new_session
?
答案 0 :(得分:3)
根据官方Python Docs,
在应用程序中存在线程时,preexec_fn参数不安全。在调用exec之前,子进程可能会死锁。如果你必须使用它,请保持琐碎!最大限度地减少您调用的库的数量。
如果您需要修改子环境,请使用env参数,而不是在preexec_fn中执行。 start_new_session参数可以代替先前常用的preexec_fn来调用子进程中的os.setsid()。
所以我想你的问题的答案是引入start_new_session
来取代使用preexec_fn
通过os.setsid()
设置会话ID的常见操作,这不是线程安全的。