【问题标题】:Using subprocess.Popen to start a program in Windows - subprocess sometimes gets stuck - is my script stable?使用 subprocess.Popen 在 Windows 中启动程序 - 子进程有时会卡住 - 我的脚本稳定吗?
【发布时间】:2021-06-05 18:40:17
【问题描述】:

作为我的 Python (3.8.2) 脚本的一部分,我通过命令行在 Windows (10) 中启动一个程序。该程序运行模拟、导出数据并关闭。我的脚本这样做了数百次。偶尔会出现 cmd 窗口但不显示任何内容(Windows 程序似乎没有执行任何操作)。我正在尝试确定问题出在外部程序还是我的脚本上。

我已经搜索过其他答案,但事实证明子流程世界很难理解。我将 Python 用于一些基本的移动/解释数据。我看到了这个答案(Understanding Popen.communicate),其中包括

注意:如果读/写不同步,这是一个非常脆弱的代码;它 死锁。

这似乎相关,但我无法理解和实施它。

我的功能是:

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

子进程卡住有什么明确的原因吗? (我不知道正确的说法是阻塞还是挂起)。

【问题讨论】:

    标签: python subprocess popen


    【解决方案1】:

    一个可行的解决方案,灵感来自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
    

    我使用timeout 变量将有关上次运行时间的信息传入/传出函数。

    【讨论】:

      猜你喜欢
      • 2014-05-09
      • 1970-01-01
      • 2017-11-12
      • 1970-01-01
      • 2018-08-06
      • 1970-01-01
      • 2017-06-20
      • 1970-01-01
      • 2011-12-24
      相关资源
      最近更新 更多