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

thread.join()在目标函数使用subprocess.run()时失效问题解决

问题根源

逻辑失效的核心原因是你调用subprocess.run()执行带&和nohup的shell命令时,shell进程会把后台任务提交后立刻退出,根本不会等待实际运行的Python业务进程结束。这就导致你的func()在后台进程刚启动时就直接执行完毕,对应线程马上退出,th.join()完全等不到后台进程跑完,自然没法实现串行。
另外你的代码里还有两处低级错误:

  • 第一段代码的for i in range(processes)行尾漏了冒号
  • 线程守护属性拼写错误,正确属性名是daemon,不是deamon
修正方案

别靠shell的nohup和&托管后台进程,直接用subprocess.Popen启动子进程、留存每个进程的句柄,等当前批次所有子进程全部执行完成后再退出func(),外层的串行逻辑就能正常生效。

修正后的任务执行函数

import subprocess
import os

def func(input_value, processes):
    process_pool = []
    # 启动对应数量的子进程,不通过shell托管
    for _ in range(processes):
        # 注意把func_background替换成脚本的实际绝对路径,避免找不到文件
        proc = subprocess.Popen(
            ["python3", "func_background", str(input_value)],
            stdout=open("nohup.out", "ab"),  # 对齐原nohup的输出重定向逻辑
            stderr=subprocess.STDOUT,
            start_new_session=True  # 实现原nohup的会话隔离效果,父进程退出不影响子进程
        )
        process_pool.append(proc)
    
    # 阻塞等待当前批次所有进程执行完毕
    for proc in process_pool:
        proc.wait()

外层调度逻辑

实际上你根本不需要引入多线程,func本身已经是阻塞执行的,直接循环调用就能实现不同input_value对应批次的串行执行:

list_input_values = [input_value_1, input_value_2]

for input_val in list_input_values:
    func(input_val, 4)
    # 只有当前input_value对应的4个进程全部跑完,才会启动下一批次

如果你一定要保留线程写法,修正之前的拼写错误即可,逻辑同样能正常运行:

import threading

list_input_values = [input_value_1, input_value_2]
for input_val in list_input_values:
    th = threading.Thread(target=func, args=(input_val, 4))
    th.daemon = True
    th.start()
    th.join()
补充提示
  • 不要随便用shell=True拼接命令,既存在命令注入风险,也会导致你拿不到实际业务进程的句柄,没法追踪进程运行状态
  • 如果需要更灵活的CPU资源控制,也可以直接用concurrent.futures.ProcessPoolExecutor限制总并发数,不用靠批次串行硬限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 00:21:54