在 Python 中的循环期间设置超时?
Setting a timeout during a loop in Python?
所以我 运行 在一个目录中循环,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"]))
要在 Python 2 上强制使用 timeout
(其中 .communicate(timeout=)
在标准库中不存在),您可以使用 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()
.
所以我 运行 在一个目录中循环,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"]))
要在 Python 2 上强制使用 timeout
(其中 .communicate(timeout=)
在标准库中不存在),您可以使用 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()
.