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

20

Linux 下使用 subprocess.Popen 开始一个新进程的两个选项: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的选项?

1个回答

20
根据官方Python文档

在应用程序中存在线程时,preexec_fn参数不安全。在调用exec之前,子进程可能会死锁。如果必须使用它,请保持其简单!尽量减少使用的库数量。

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接