【问题标题】:Setting a timeout during a loop in Python?在 Python 中的循环期间设置超时?
【发布时间】:2016-01-16 12:01:59
【问题描述】:

所以我在一个目录中运行一个循环,由 subprocess.Popen 运行的外部脚本在该目录中移动并对每个文件执行计算。外部脚本有点不稳定,当它遇到不知道如何处理的文件时偶尔会冻结。有没有办法向 subprocess.Popen 添加超时功能,以便我可以跳过该文件并继续下一个?

编辑: 这是我的循环:

def automate():
    os.chdir("/home/mlts/dir")
    working_dir = b"/home/mts/dir"
    for filename in os.listdir(working_dir):
        if filename.endswith(".MTS"):
            try:
                print("Performing calculations on {filename!r}...".format(**vars()))
                try:
                    os.remove("mts_tbl.txt")
                except OSError:
                    pass
                time.sleep(3)
                p = Popen(["run_command.command", "-f", "a"], cwd=working_dir, stdin=PIPE)
                p.communicate(input=b"\n".join([b"1", str(filename), b"8", b"alloy-liquid", b"0", b"x", b"5", b"4", b"-1.6", b"4", b"1", b"0"]))

【问题讨论】:

  • 一个可以帮助您完成超时部分,但要跳过文件脚本冻结,您必须提供代码
  • 知道了。编辑提供...
  • 你错过了 os.chdir 行的最后一个 "
  • 一次做两件事,1=运行函数,2=经过一定时间后取消,你使用多处理或线程。就个人而言,我会将该函数称为多处理进程,并在允许的时间过去后终止该进程。 Doug Hellmann 的页面位于 pymotw.com/2/multiprocessing/basics.html#terminating-processes
  • 这种方法是否允许继续循环到目录中的下一个文件?

标签: python loops timeout subprocess


【解决方案1】:

要在 Python 2 上强制使用 timeout(其中 .communicate(timeout=) 在 stdlib 中不存在),您可以使用 threading.Timer()

p = Popen(...)
t = Timer(3, p.kill) # kill in 3 seconds
t.start()
p.communicate(...)
t.cancel() # no need to kill, the process is dead already

完整的例子:

import os
import traceback
from glob import glob
from subprocess import Popen, PIPE
from threading import Timer

os.chdir("/home/mls/dir") #XXX assume mlts is a typo in the question
for filename in glob(b"*.MTS"):
    print("Performing calculations on {filename!r}...".format(**vars()))
    try:
        os.remove("mts_tbl.txt")
    except OSError:
        pass # ignore
    try:
        p = Popen(["run_command.command", "-f", "a"], stdin=PIPE) #XXX no cwd
        t = Timer(3, p.kill)
        t.start()
        p.communicate(input=b"\n".join([b"1", filename,
                b"8\nalloy-liquid\n0\nx\n5\n4\n-1.6\n4\n1\n0"]))
        t.cancel()
    except Exception:
        traceback.print_exc()

此代码假定您要在父 Python 脚本的当前工作目录中运行子进程。

在 Python 3 上或如果安装了 subprocess32;您可以将timeout 参数传递给.communicate() 方法,而不是使用Timer()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-18
    • 1970-01-01
    • 1970-01-01
    • 2020-03-01
    • 1970-01-01
    • 2017-08-06
    • 1970-01-01
    相关资源
    最近更新 更多