14

subprocess.Popen使用for python3.2+under启动新进程的这两个选项有什么区别Linux

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)测试了我的代码,它们似乎对我来说都可以正常工作。

但我想知道这里最好的选择是什么——一个 withpreexec_fn还是那个 with start_new_session

4

1 回答 1

16

根据官方Python 文档

在应用程序中存在线程的情况下,使用 preexec_fn 参数是不安全的。在调用 exec 之前,子进程可能会死锁。如果您必须使用它,请保持微不足道!尽量减少调用的库数量。

如果您需要修改孩子的环境,请使用 env 参数,而不是在 preexec_fn 中进行。start_new_session 参数可以代替以前常用的 preexec_fn 在子进程中调用 os.setsid()。

所以我想你的问题的答案是,它start_new_session被引入来替换使用preexec_fn通过设置会话ID的常见操作os.setsid(),这不是线程安全的。

于 2017-06-22T17:35:05.637 回答