You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中仅重定向子进程stdout至文件失效问题求助

问题描述

parent.py:

from mpi4py import MPI
import sys

comm = MPI.COMM_WORLD

for i in range(10):
    print(something)
    child_comm = MPI.COMM_WORLD.Spawn(sys.executable, args=['child.py'], maxprocs=9)
    child_comm.Disconnect()

child.py:

import sys

sys.stdout = open("analysis_log.txt", "a")

# 运行求解器相关代码

sys.stdout.close()

需求是仅重定向child.py的输出(求解器底层为Fortran编译代码,通过Fortran的write/print语句输出内容),但通过修改sys.stdout或contextlib.redirect_stdout均无法生效,而终端重定向>>却可以正常工作。请问如何解决该问题?为什么会出现这种差异?

Python版本:3.8.13


原因分析

Python的sys.stdout仅负责处理Python层面的输出流,而Fortran编译的二进制代码直接操作的是系统级别的标准输出文件描述符(file descriptor),二者不属于同一层级。终端重定向>>是操作系统层面的操作,会直接修改整个进程的标准输出文件描述符,因此能覆盖Python和Fortran的所有输出。


解决方案

方案1:Spawn子进程时通过MPI参数指定重定向

在调用MPI.Spawn时,通过info参数设置系统级的输出重定向,无需修改child.py即可覆盖所有语言的输出:

修改parent.py中的Spawn调用:

from mpi4py import MPI
import sys

comm = MPI.COMM_WORLD

info = MPI.Info.Create()
# 设置stdout和stderr追加到日志文件
info.Set("stdout", "analysis_log.txt")
info.Set("stderr", "analysis_log.txt")
info.Set("append", "1")  # 启用追加模式

for i in range(10):
    print(something)
    child_comm = MPI.COMM_WORLD.Spawn(
        sys.executable,
        args=['child.py'],
        maxprocs=9,
        info=info
    )
    child_comm.Disconnect()

info.Free()

方案2:在child.py中修改系统文件描述符

直接操作系统级文件描述符,替换stdout/stderr的指向,覆盖所有输出流:

修改child.py:

import os

# 打开日志文件,获取文件描述符(O_CREAT确保文件不存在时创建)
log_fd = os.open("analysis_log.txt", os.O_WRONLY | os.O_APPEND | os.O_CREAT)
# 将stdout(1)和stderr(2)的文件描述符替换为日志文件的fd
os.dup2(log_fd, 1)
os.dup2(log_fd, 2)
# 关闭原文件描述符
os.close(log_fd)

# 运行求解器相关代码

方案3:通过Shell命令实现重定向

利用Shell的重定向功能,在Spawn时直接调用Shell执行命令:

修改parent.py中的Spawn调用:

child_comm = MPI.COMM_WORLD.Spawn(
    'bash',
    args=['-c', f'{sys.executable} child.py >> analysis_log.txt 2>&1'],
    maxprocs=9
)

内容的提问来源于stack exchange,提问作者Pavan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 08:11:27