python中startout是什么意思_python中subprocess.Popen preexec_fn和start_new_session之间的区别...

What is the difference between these two options to start a new process with 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

I need this as I need to set process group ID to have a possibility to kill at once this process and all of its children. This is then used in the case if the process run time exceeds certain threshold:

try:

out, err = proc.communicate(timeout=time_max)

except subprocess.TimeoutExpired:

os.killpg(os.getpgid(proc.pid), signal.SIGTERM)

I tested my code with the both options (#1 & #2) and they both seem to work ok for me.

But I wonder what is the best option here - the one with preexec_fn or the one with start_new_session?

解决方案

According to the official 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.

So I guess the answer to your question is that start_new_session was introduced to replace the common operation of using preexec_fn to set the session id through os.setsid(), which is not thread safe.

### subprocess.Popen 参数详解 #### 基本概念 `subprocess.Popen()` 是 Python 的 `subprocess` 模块中的一个重要类,用于创建新的进程并连接到它们的输入/输出/错误管道,从而获取返回码。此方法提供了极大的灵活性来控制子进程的行为。 #### 主要参数说明 - **args**: 表示要执行命令及其参数。可以是字符串或序列(如列表)。当传递给 `Popen` 时,如果是字符串,则通常需要设置 `shell=True` 才能正常解析命令;而作为序列提供时,默认情况下不需要指定 `shell=True` 即可正确处理多个参数[^4]。 - **bufsize**: 缓冲区大小选项,影响标准流如何被缓冲。常见值有 `-1` (默认),表示使用操作系统默认行为;`0` 表示无缓冲;正整数则指定了固定大小的缓冲区。 - **executable**: 可选参数,在某些平台上用来替代第一个参数 (`args`) 中的第一个元素所指向的实际二进制文件位置。这主要用于 Windows 平台上的特殊情况。 - **stdin**, **stdout**, **stderr**: 控制新进程中标准输入、输出错误的方式。这些参数接收 None 或者 PIPE。如果设为 PIPE,则可以通过调用对象的方法读取写入数据。另外还可以通过 file descriptor 文件描述符等方式关联现有打开的文件句柄。 - **preexec_fn**: Unix 特有的功能,允许在启动子进程之前运行一个自定义函数来进行额外配置操作。 - **close_fds**: 如果该标志位为真,则除了那些显式保留下来的外,所有其他未关闭的文件描述符都会自动关闭。这对于防止资源泄漏非常重要。 - **cwd**: 设置子进程的工作目录路径。如果不设定,默认会继承父进程当前所在的位置。 - **env**: 定义环境变量字典供子进程使用。同样不特别指出的话,也会沿用父进程现有的环境设置。 - **universal_newlines**: 启用了这一选项之后,所有的 I/O 都将以文本模式而不是二进制形式进行交互,并且换行符会在不同平台之间得到统一转换。 - **startupinfo** **creationflags**: 这两个参数仅适用于 Windows 系统,分别用于定制窗口外观以及附加更多关于创建过程的信息标记。 - **restore_signals**, **start_new_session**, **pass_fds**: 更高级别的跨平台特性支持,具体细节参见官方文档。 #### 示例代码展示 下面给出几个简单的例子来演示上述部分参数的具体应用: ```python import subprocess # 使用列表方式传入命令及参数 proc = subprocess.Popen( ['echo', 'hello world'], stdout=subprocess.PIPE, ) output, error = proc.communicate() print(output.decode()) # 使用字符串加 shell=True 方式传入复杂 Shell 命令 proc_shell = subprocess.Popen( "echo hello && echo again", shell=True, stdout=subprocess.PIPE, ) output_shell, _ = proc_shell.communicate() print(output_shell.decode()) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值