[英]Asyncio Terminate Subprocess on wait_for timeout
I have a long running process and its children (in this example it is stress
) that I wish to terminate after some time.我有一个长时间运行的进程及其子进程(在这个例子中是
stress
),我希望在一段时间后终止。 I am using asyncio.wait_for
since it's what the documentation suggests, but while the timeout occurs and the asyncio.TimeoutError
is raised, the process is still running.我正在使用
asyncio.wait_for
因为它是文档所建议的,但是当发生超时并且引发asyncio.TimeoutError
时,进程仍在运行。 I'm running on Python 3.8.10.我在 Python 3.8.10 上运行。
Here's my code:这是我的代码:
import asyncio
async def run(cmd):
print("Running: ", cmd)
proc = await asyncio.create_subprocess_exec(
*cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE)
stdout, stderr = await proc.communicate()
stdout = stdout.decode('UTF-8')
stderr = stderr.decode('UTF-8')
return (stdout, stderr, proc.pid, proc.returncode)
async def run_with_timeout(cmd, timeout=20):
task = asyncio.wait_for(run(cmd), timeout=timeout)
try:
output = await task
stdout, _, pid, _ = output
return str(stdout).strip()
except asyncio.TimeoutError as e:
print("Terminating Process '{0}' (timed out)".format(cmd))
asyncio.run(run_with_timeout(['stress', '--cpu', '2'], timeout=5))
Can someone suggest a way to kill this process after the timeout?有人可以建议一种在超时后终止此进程的方法吗? Thanks in advance: :D
提前致谢
I ended up solving it by modifying the functions a bit.我最终通过稍微修改函数来解决它。 Before, my
run()
function returned the output of the command.之前,我的
run()
function 返回了命令的output。 By returning the process proc
, I could monitor the timeout for the proc.communicate()
.通过返回进程
proc
,我可以监控proc.communicate()
的超时。 This is the portion that waits until the process is done.这是等待过程完成的部分。 If the process takes longer than
timeout
, then I ask if it is done, by looking into proc.returncode
.如果该过程花费的时间超过
timeout
,那么我会通过查看proc.returncode
询问它是否完成。 If it is other than None
it has finished.如果它不是
None
则它已经完成。 If it is None
, then I recursively kill every child and finally the parent process itself.如果它是
None
,那么我递归地杀死每个孩子,最后杀死父进程本身。
async def run(cmd):
print("Running: ", cmd)
proc = await asyncio.create_subprocess_exec(
*cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE)
return proc
async def run_with_timeout(cmd, timeout=20):
proc = await run(cmd)
try:
output = await asyncio.wait_for(proc.communicate(), timeout=timeout)
stdout, _ = output
return str(stdout).strip()
except asyncio.TimeoutError:
if proc.returncode is None:
parent = psutil.Process(proc.pid)
for child in parent.children(recursive=True):
child.terminate()
parent.terminate()
print("Terminating Process '{0}' (timed out)".format(cmd))
asyncio.run(run_with_timeout(['stress', '--cpu', '2'], timeout=5))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.