python中subprocess.Popen preexec_fn和start_new_session之间的区别

Mik*_*yer 5 python subprocess popen kill-process setsid

是什么启动一个新的进程与这两个选项之间的区别subprocess.Popenpython3.2+Linux

proc = subprocess.Popen(args, ..., preexec_fn=os.setsid)   # 1
proc = subprocess.Popen(args, ..., start_new_session=True) # 2
Run Code Online (Sandbox Code Playgroud)

我需要这个,因为我需要设置进程组ID,以便有可能立即杀死该进程及其所有子进程。然后,如果流程运行时间超过特定阈值,则使用此方法:

try:
    out, err = proc.communicate(timeout=time_max)
except subprocess.TimeoutExpired:
    os.killpg(os.getpgid(proc.pid), signal.SIGTERM) 
Run Code Online (Sandbox Code Playgroud)

我使用两个选项(#1#2)测试了我的代码,它们对我来说似乎都可以正常工作。

但是我想知道这里最好的选择是什么-一个preexec_fn或一个start_new_session

Sha*_*aun 15

根据官方Python Docs

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

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

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