Python:结束无限迭代的子流程

时间:2013-07-15 18:47:17

标签: python subprocess popen

我有一个使用子进程模块打开.exe程序的python脚本。此.exe程序是一个无限迭代的脚本,因为它将继续打印每次迭代的结果,直到用户关闭窗口。它经常会将迭代结果打印到文件中,替换文件中的先前数据。

我的目标是:

  1. 运行.exe程序,并测试它输出的文件是否存在。
  2. 一旦文件显示存在,我需要对文件运行一个测试,看看迭代是否收敛到给定的容差范围内。一旦迭代收敛,我就需要杀死.exe子进程。
  3. 这是我目前的代码。它被设计为在创建迭代文件后终止子进程:

    import subprocess
    from subprocess import Popen, PIPE
    
    fileexists = False
    
    iteratecomms = Popen('iterate.exe', stdout=PIPE, stdin=PIPE, stderr=PIPE)
    
    # Begin the iteration. Need to select options 1 and then 1 again at program menu
    out, err = iteratecomms.communicate("1\n1\n".encode())
    
    while (fileexists == False):
        fileexists = os.path.exists(filelocation)
    else:
        Popen.kill(iteratecomms)
    

    我知道这是不正确的;问题是,只要我启动out, err = iteratecomms.communicate("1\n1\n".encode())行,程序就会开始迭代,而不会转到下一组python代码。本质上,我需要启动.exe程序,同时测试是否已创建该文件。但是,我不能这样做,因为该程序无限期地运行。

    我怎么能绕过这个?我假设继续执行第2步(在某些条件下测试文件并杀死子进程)不会在此基础上进行太多工作;如果不是这样,我将如何完成所有目标?

    非常感谢您的帮助!

    修改:澄清外部文件被覆盖。

2 个答案:

答案 0 :(得分:1)

假设您正在尝试不断尝试阅读此文件,我建议您对相关文件运行tail。这可以通过任何* nix系列操作系统中的单独终端来完成,但是否则我会查看本文以获得Python实现:

http://code.activestate.com/recipes/157035-tail-f-in-python/

之后,如果你想杀死运行的程序,你应该只能在运行的进程上调用terminate:

import subprocess
sub = subprocess.popen(#Whatever)

#Do something

sub.terminate()

答案 1 :(得分:1)

我会使用多处理模块。

pool = multiprocessing.Pool()
def start_iteration():
    return Popen('iterate.exe', stdout=PIPE, stdin=PIPE, stderr=PIPE)
pool.apply_async(start_iteration)
while (fileexists == False):
    fileexists = os.path.exists(filelocation)
Popen.kill(???)

现在唯一的问题是你必须以某种方式找到进程的PID而不等待Popen返回(因为Popen永远不会返回。)