【问题标题】:python: subprocess returns nothing when running scripts which take longer timepython:运行需要较长时间的脚本时,子进程不返回任何内容
【发布时间】:2021-01-27 08:44:40
【问题描述】:

这里有subrpocess问题的初学者:

当我用更少的数据运行两个脚本时,下面的行工作正常,大约需要 10-20 分钟,但是如果要处理更大的数据,一旦两个脚本都完成,子进程就不会返回任何内容(假设在一小时内)。

另外:通常在数据较少的情况下,它的行为也会异常,即不返回 status_code/通过。然后我必须再次运行 sn-p 并且它可以工作。任何可靠的推理都会有很大帮助!

 status_code = subprocess.run(f"python3 scriptA.py {param_1} & python3 scriptB.py {param_2}",
                                     shell=True).returncode

 if status_code == 0:
     print("subprocess ended ..")  # the control does not come here incase of huge files          
     some_other_file.main(some_param1, some_param2)

我不明白为什么会发生这种情况(或者我应该使用不同的方法吗?),非常感谢任何帮助。谢谢!

脚本示例(scriptA 和 scriptB):

def main(param_2):
    some_func_with_csv_operations()  # not returning anything
    more_funcs()

if __name__ == "__main__":
    param_2 = sys.argv[1]
    main(param_2)

另外,没有任何 scriptA 或 scriptB sys.exit()

编辑:

截图:

尝试在if 条件之前打印status_code,没有打印任何内容,在终端中,我看到一个光标在闪烁。

enter image description here

另外(寻找任何 python 进程): 使用ps -ax | grep python显示没有相关信息(附图)

enter image description here

【问题讨论】:

  • 这意味着返回的状态码不是 0。这意味着通过 subprocess.run() 调用的脚本之一遇到了错误。这意味着您应该首先检查这些脚本,它们为什么会出错。
  • @pepoluan 不,脚本很好。当脚本使用较少的数据运行时,通常会发生这种情况。有时它会通过,有时它不会返回 status_code。当两个脚本都完成时。我使用ps -ax | grep python 进行检查,发现没有运行 python 脚本。
  • 您有什么理由在一个子进程中运行两个脚本吗?将两个脚本分成两个子进程将帮助您了解故障发生在哪里
  • 你可以在python中并行运行两个子进程。使用Popen 构造函数而不是run 函数,然后在收集返回码之前在每个进程上调用wait。如果你这样做,你也不需要shell=True。
  • @Shannon 可以将其作为答案发布吗?也许与 Popen 相当的一些细节(做我在 subprocess.run 中的工作)会有所帮助

标签: python python-3.x multithreading shell subprocess


【解决方案1】:

尝试单独运行您的进程以更好地了解故障发生在哪里

running_processes = []
running_processes.append(subprocess.Popen(["python3", "scriptA.py", f"{param_1}"]))
running_processes.append(subprocess.Popen(["python3", "scriptB.py", f"{param_2}"]))

both_succeeded = True
for p in running_processes:
    ret = p.wait()
    if ret:   # anything other than zero will evaluate to True here
        both_succeeded = False
    cmd = " ".join(p.args)
    print(f'command "{cmd}" returned code {ret}'

if both_succeeded:
    do_more_things()

上面使用列表来保存正在运行的进程,以便您可以循环处理它们并避免重复代码。如果您肯定只有两个子流程,您可以选择不使用循环。

process1 = subprocess.Popen(shlex.split(f"python3 scriptA.py {param_1}"))
process2 = subprocess.Popen(shlex.split(f"python3 scriptB.py {param_2}"))

ret1 = process1.wait()
ret2 = process2.wait()

if ret1 == 0 and ret2 == 0:  # or "if not ret1 and not ret2:" would also work
    do_more_things()

注意Popen 需要一个参数列表并且不接受单个字符串,但我在此示例中使用了shlex.split 以允许对命令使用单个字符串并获得相同的结果。

【讨论】:

  • 我应该在哪里添加if 条件?
  • 如果两个子进程都返回成功,您是否要运行其他代码?
  • 是的,一旦两个子进程都返回成功,我想调用另一个方法:some_other_file.main(some_param1, some_param2) 就像你在我原来的问题中看到的那样
  • shlex 定义在哪里?
  • 你需要import shlex,就像你已经拥有import subprocess
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-01
  • 2018-07-02
  • 1970-01-01
相关资源
最近更新 更多