【问题标题】:Python: Ending an infinitely iterative subprocessPython:结束无限迭代的子进程
【发布时间】:2013-07-15 18:47:17
【问题描述】:

我有一个 python 脚本,它使用 subprocess 模块打开一个 .exe 程序。这个 .exe 程序是一个无限迭代的脚本,它会继续打印每次迭代的结果,直到用户关闭窗口。每隔一段时间,它就会将迭代的结果打印到一个文件中,替换文件中之前的数据。

我的目标是:

  1. 运行 .exe 程序,并测试它输出的文件是否存在。
  2. 一旦文件显示存在,我需要对文件运行测试以查看迭代是否收敛到给定容差范围内。迭代收敛后,我需要终止 .exe 子进程。

这是我当前的代码。它旨在在创建迭代文件后终止子进程:

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 步(在某些条件下测试文件并终止子进程)不会在此之上花费太多工作;如果这不是真的,我将如何完成我的所有目标?

非常感谢您的帮助!

编辑:澄清外部文件已被覆盖。

【问题讨论】:

  • 避免挂断communicate("1\n1\n".encode()),而是致电Popen.stdin.write("1\n1\n".encode())
  • 这行得通(当我用iteratecomms替换Popen时);谢谢你!您知道如何使用iteratecomms.stdout.read() 之类的东西连续打印 .exe 程序的输出吗?
  • 在我的脑海中,我设置了一个单独的线程,通过iteratecomms.stdout.read() 连续读取行并将它们放入主线程检查并检索它们的Queue。这个单独的线程在不再需要时很容易被杀死。
  • 另外,Non-blocking read on a subprocess.PIPE in python 问题的答案可能对您有所帮助。 (或者至少让你知道要寻找什么样的东西)。

标签: python subprocess popen


【解决方案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 永远不应该返回。)

【讨论】:

【解决方案2】:

假设您正在尝试不断尝试读取此文件,我建议您在相关文件上运行 tail。这可以从任何 *nix 系列操作系统中的单独终端完成,否则我会查看这篇文章以了解 Python 实现:

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

之后,如果你想杀死正在运行的程序,你应该能够在正在运行的进程上调用终止:

import subprocess
sub = subprocess.popen(#Whatever)

#Do something

sub.terminate()

【讨论】:

  • 道歉;我是 Python 和 subprocess 模块的初学者。我不太明白这实际上如何适用于我的问题!这个tail使用file.tell(),好像是在文件中找到当前指针位置;我使用的文件在每次迭代后被替换;即一旦创建文件,当前迭代数据将替换最后一组。我遇到的问题是创建文件的时间。如果我错过了您的观点,真的很抱歉!
  • @FreeBix 等等,我可能理解错了。您的迭代是否不断删除和重新创建单个文件?
  • @FreeBix Omigoodness。如果您可以控制该代码,我会高度出于十亿个不同的原因建议追加而不是重写。除此之外,我建议在页面上向下滚动查看 tail 函数的“last n”版本,它只会让您查看最后一行或几行并确定它是否符合您的标准。如果您需要查看所有内容,只需将 last n 更改为一些非常大的数字。
  • 不幸的是,我无法控制该代码,否则我不会让自己经历这些。我还需要考虑我必须比较整个输出文件中的值,而不仅仅是最后一行。非常感谢您的建议;在这个问题上花了一整天的时间,我明天会用一双新的眼睛试试!
  • @FreeBixi 如果您要阅读整个内容,您应该只写入标准输出而不是文件。
猜你喜欢
  • 2017-06-06
  • 1970-01-01
  • 2012-09-24
  • 2017-12-12
  • 1970-01-01
  • 1970-01-01
  • 2010-09-12
  • 1970-01-01
相关资源
最近更新 更多