简体   繁体   English

使用 subprocess.Popen 在 Windows 中启动程序 - 子进程有时会卡住 - 我的脚本稳定吗?

[英]Using subprocess.Popen to start a program in Windows - subprocess sometimes gets stuck - is my script stable?

As part of my Python (3.8.2) script, I start a program in Windows (10) via command line.作为我的 Python (3.8.2) 脚本的一部分,我通过命令行在 Windows (10) 中启动一个程序。 This program runs a simulation, exports data, and closes.该程序运行模拟、导出数据并关闭。 My script does this hundreds of times.我的脚本这样做了数百次。 Very occasionally, the cmd window appears but displays nothing (the Windows program does not seem to be doing anything).偶尔,cmd window 出现但什么也不显示(Windows 程序似乎没有做任何事情)。 I am trying to determine whether the problem is with the external program, or my script.我正在尝试确定问题出在外部程序还是我的脚本上。

I have searched for other answers but the subprocess world is proving difficult to understand.我已经搜索了其他答案,但事实证明子流程世界很难理解。 I use Python for some basic moving/interpreting data.我使用 Python 来获取一些基本的移动/解释数据。 I saw this answer ( Understanding Popen.communicate ), which includes我看到了这个答案( Understanding Popen.communicate ),其中包括

Note: it is a very fragile code if read/write are not in sync;注意:如果读/写不同步,这是一个非常脆弱的代码; it deadlocks.它陷入僵局。

This seems relevant but I am not in a position to understand & implement it.这似乎是相关的,但我不在 position 中理解和实施它。

My function is:我的 function 是:

def run_program(args):
    cmd = #defined by args
    p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    stdout, stderr = p.communicate()
    variables = #read from some datafiles created by the program that was run
    return variables

Is there any clear reason why the subprocess gets stuck?子进程卡住有什么明确的原因吗? (I don't know if the correct term is blocks or hangs). (我不知道正确的术语是阻塞还是挂起)。

A working solution, with inspiration from How to kill subprocess if no activity in stdout/stderr一个可行的解决方案,灵感来自How to kill subprocess if no activity in stdout/stderr

def run_program(args, timeout):
    cmd = [] #defined by args
    if timeout == 'default':
        timeout = 600
    tries = 0
    while tries < 4:
        tries += 1
        try:
            p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
            t = 0
            while p.poll() != 0:
                if t > timeout:
                    raise RuntimeError('Timeout')
                    break
                time.sleep(1)
                t+=1
            successful = True
        except RuntimeError:
            kill = subprocess.Popen("TASKKILL /F /PID {pid} /T".format(pid=p.pid))
            # some actions for this condition
            successful = False
        if successful == True:
            # some actions for this condition
            break
    return variables, t

I use the timeout variable to pass information about the last run time in/out of the function.我使用timeout变量将有关上次运行时间的信息传入/传出 function。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM