需要:
Python 3子进程模块内置了timeout,我也尝试使用计时器和使用线程来实现超时,但它并不适用于输出。 readline()
是否阻止? readlines()
肯定会在吐出所有输出之前等待进程结束,这不是我需要的(我需要继续)。
我接近切换到node.js: - (
答案 0 :(得分:4)
我会使用asyncio来完成这类任务。
从过程中读取IO,就像在此接受的anwser中一样: How to stream stdout/stderr from a child process using asyncio, and obtain its exit code after?
(我不想在这里完全复制)
将其包裹在超时中:
async def killer(trans, timeout):
await asyncio.sleep(timeout)
trans.kill()
print ('killed!!')
trans, *other_stuff = loop.run_until_complete(
loop.subprocess_exec(
SubprocessProtocol, 'py', '-3', '-c', 'import time; time.sleep(6); print("Yay!")' ,
)
)
asyncio.ensure_future(killer(trans, 5)) # 5 seconds timeout for the kill
loop.run_forever()
玩得开心......
答案 1 :(得分:0)
使用下面的2 python脚本。
Master.py 将使用Popen
启动新进程并启动一个观察程序线程,该线程将在3.0
秒后终止该进程。
如果写入stdout
的数据中没有换行符,则必须调用flush方法(在'\n'
的窗口上也会导致刷新)。
注意
time
模块不是高精度计时器。在极端情况下(从具有USB 1.0的闪存驱动器读取可执行文件),进程的加载时间可能超过3.0秒
<强> Master.py 强>
import subprocess, threading, time
def watcher(proc, delay):
time.sleep(delay)
proc.kill()
proc = subprocess.Popen('python Slave.py', stdout = subprocess.PIPE)
threading.Thread(target = watcher, args = (proc, 3.0)).start()
data = bytearray()
while proc:
chunk = proc.stdout.read(1)
if not chunk:
break
data.extend(chunk)
print(data)
<强> Slave.py 强>
import time, sys
while True:
time.sleep(0.1)
sys.stdout.write('aaaa')
sys.stdout.flush()
答案 2 :(得分:0)
在 Python 3.7 + 上,将subprocess.run()
与capture_output=True
和timeout=<your_timeout>
结合使用。如果命令在<your_timetout>
秒之前没有返回,它将终止进程并引发subprocess.TimeoutExpired
异常,该异常将具有.stdout
和.stderr
属性:
import subprocess
try:
result = subprocess.run(["sleep", "3"], timeout=2, capture_output=True)
except subprocess.TimeoutExpired as e:
print("process timed out")
print(e.stdout)
print(e.stderr)
您可能还希望传递text=True
(或在Python <3.7上传递universal_newlines=True
),以使stdout
和stderr
是str
而不是{{ 1}}。
在旧版本的Python上,您需要在调用bytes
时将capture_output=True
替换为stdout=subprocess.PIPE, stderr=subprocess.PIPE,
,其余的应该相同。
编辑:这不是您想要的,因为您需要等待进程终止以读取输出,但这就是我遇到这个问题时想要的。