我编写了一些代码来运行脚本(通过子进程)并在一定的超时后终止子进程。我正在运行一个名为“ runtime_hang_script.sh”的脚本,该脚本仅包含“ ./runtime_hang”,该脚本运行无限循环。我还将stdout重定向到管道-我计划将其同时写入sys.stdout和文件(也就是我试图实现tee)。但是,我的代码在子进程超时后挂起。请注意,仅在运行“ sh runtime_hang_script.sh”而不是“ ./runtime_hang”时挂起。另外,当我尝试直接管道传输到文件或不从管道读取数据时,该消息也不会挂起。
我尝试了创建定时子流程的其他实现,但是我一直遇到同样的问题。我什至尝试在问题结束时发出信号-出于某种原因,信号发出的时间比预期的要早,因此这也不起作用。任何帮助,将不胜感激。预先感谢!
process = None
def run():
global process
timeout_secs = 5
args = ['sh', 'runtime_hang_script.sh']
sys.stdout.flush()
process = subprocess.Popen(args, stdout=subprocess.PIPE, bufsize=1)
with process.stdout:
for line in iter(process.stdout.readline, b''):
sys.stdout.write(line.decode('utf-8'))
sys.stdout.flush()
process.wait()
proc_thread = threading.Thread(target=run)
proc_thread.start()
proc_thread.join(5)
print(proc_thread.is_alive())
if proc_thread.is_alive():
process.kill()
答案 0 :(得分:0)
假设您使用的是Python 3.3或更高版本,则可以使用subprocess.communicate()
方法的timeout参数来实现5秒钟的超时:
import subprocess
import sys
timeout_secs = 5
args = ['sh', 'runtime_hang_script.sh']
process = subprocess.Popen(args, stdout=subprocess.PIPE, bufsize=1)
try:
print("Waiting for data from child process...")
(stdoutData, stderrData) = process.communicate(None, timeout_secs)
print("From child process: stdoutData=[%s] stderrData=[%s]" % (stdoutData, stderrData))
except subprocess.TimeoutExpired:
print("Oops, child process took too long! Now it has to die")
process.kill()
print("Waiting for child process to exit...")
process.wait()
print("Child process exited.")
请注意,使用此方法无需生成子线程,因为超时可以直接在主线程中起作用。