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

Difference between subprocess.Popen preexec_fn and start_new_session in python

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

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

根据官方Python Docs,

The preexec_fn parameter is not safe to use in the presence of threads in your application. The child process could deadlock before exec is called. If you must use it, keep it trivial! Minimize the number of libraries you call into.

If you need to modify the environment for the child use the env parameter rather than doing it in a preexec_fn. The start_new_session parameter can take the place of a previously common use of preexec_fn to call os.setsid() in the child.

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