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

Python subprocess.run超时未终止子进程问题求助

问题原因及解决方案

核心问题1:shell=True导致超时无法终止实际转换进程

当使用shell=True时,subprocess.run启动的是系统shell进程(如bash),再由shell去启动ebook-convert。此时timeout参数只会终止shell进程,而ebook-convert会成为孤儿进程被系统接管,继续在后台运行,导致你的主程序要么卡在等待状态,要么看似正常执行但实际转换任务并未停止。

核心问题2:代码结构错误,超时异常未被捕获

你的subprocess.run调用在try块之外,一旦触发TimeoutExpired异常,会直接终止程序,无法进入后续的异常处理逻辑。


解决方案1:移除shell=True(推荐)

直接传递命令参数列表给subprocess.run,这样timeout会直接终止ebook-convert进程,同时避免shell注入风险,代码更安全:

try:
    cmd = ['ebook-convert', filename, outfile]
    process = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=77400)

    ConversionFile.set_to_finished(options.get('uuid'))

    if process.stderr and "error" in process.stderr.decode("utf-8"):
        return {'error': process.stderr.decode("utf-8")}
    return [outfile]
except subprocess.TimeoutExpired:
    print("转换超时,已终止进程")
    return {'error': '转换超时'}
except Exception as e:
    print(str(e))
    return {'error': str(e)}

解决方案2:保留shell=True但终止整个进程组

如果因特殊需求必须使用shell=True,可以通过start_new_session=True创建新的进程组,超时后终止整个进程组,确保ebook-convert也被杀死:

import os
import signal

try:
    cmd = 'ebook-convert "%s" "%s"' % (filename, outfile)
    # 创建新进程组,关联shell和子进程
    process = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, 
                            timeout=77400, start_new_session=True)

    ConversionFile.set_to_finished(options.get('uuid'))

    if process.stderr and "error" in process.stderr.decode("utf-8"):
        return {'error': process.stderr.decode("utf-8")}
    return [outfile]
except subprocess.TimeoutExpired:
    # 终止整个进程组,包含shell和ebook-convert
    os.killpg(os.getpgid(process.pid), signal.SIGTERM)
    # 强制终止(可选,确保进程彻底退出)
    os.killpg(os.getpgid(process.pid), signal.SIGKILL)
    print("转换超时,已终止所有相关进程")
    return {'error': '转换超时'}
except Exception as e:
    print(str(e))
    return {'error': str(e)}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 22:03:33