杀死一个 python 没有 return 的子进程
Kill a python subprocess that does not return
TLDR 我想在它还在 运行ning
时杀死像 top 这样的子进程
我正在使用 Fastapi 运行 输入命令。例如,如果我在我的程序顶部输入 运行s 命令,但由于它没有 return,此时我必须使用时间延迟然后 kill/terminate 它。但是,我希望能够在它还在 运行ning 时将其杀死。但是目前它不会 运行 我的 kill 命令,直到 运行 结束。
这是 运行 进程的当前代码:
@app.put("/command/{command}")
async def run_command(command: str):
subprocess.run([command], shell=True, timeout=10)
return {"run command"}
并杀死它
@app.get("/stop")
async def stop():
proc.kill()
return{"Stop"}
我是 fastapi 的新手,所以如果有任何帮助,我将不胜感激
这是因为 subprocess.run
正在阻止自己 - 您需要在后台执行 运行 shell 命令,例如如果你已经打开了 asnycio 循环,你可以使用 subprocesses
import asyncio
process = None
@app.get("/command/{command}")
async def run_command(command: str):
global process
process = await asyncio.create_subprocess_exec(
command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
)
return {"run command"}
@app.get("/stop")
async def stop():
process.kill()
return {"Stop"}
或 Popen
from subprocess import Popen
process = None
@app.get("/command/{command}")
async def run_command(command: str):
global process
process = Popen([command]) # something long running
return {"run command"}
添加超时选项可能会很棘手,因为您不想等到它完成(您确实可以使用 wait_for 函数),而是在特定时间后终止进程。据我所知,最好的选择是安排负责杀死主要进程的其他进程。使用 asyncio 的代码可能如下所示:
@app.get("/command/{command}")
async def run_command(command: str):
global process
process = await asyncio.create_subprocess_exec(
command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
)
loop = asyncio.get_event_loop()
# We schedule here stop coroutine execution that runs after TIMEOUT seconds
loop.call_later(TIMEOUT, asyncio.create_task, stop(process.pid))
return {"run command"}
@app.get("/stop")
async def stop(pid=None):
global process
# We need to make sure we won't kill different process
if process and (pid is None or process.pid == pid):
process.kill()
process = None
return {"Stop"}
TLDR 我想在它还在 运行ning
时杀死像 top 这样的子进程
我正在使用 Fastapi 运行 输入命令。例如,如果我在我的程序顶部输入 运行s 命令,但由于它没有 return,此时我必须使用时间延迟然后 kill/terminate 它。但是,我希望能够在它还在 运行ning 时将其杀死。但是目前它不会 运行 我的 kill 命令,直到 运行 结束。
这是 运行 进程的当前代码:
@app.put("/command/{command}")
async def run_command(command: str):
subprocess.run([command], shell=True, timeout=10)
return {"run command"}
并杀死它
@app.get("/stop")
async def stop():
proc.kill()
return{"Stop"}
我是 fastapi 的新手,所以如果有任何帮助,我将不胜感激
这是因为 subprocess.run
正在阻止自己 - 您需要在后台执行 运行 shell 命令,例如如果你已经打开了 asnycio 循环,你可以使用 subprocesses
import asyncio
process = None
@app.get("/command/{command}")
async def run_command(command: str):
global process
process = await asyncio.create_subprocess_exec(
command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
)
return {"run command"}
@app.get("/stop")
async def stop():
process.kill()
return {"Stop"}
或 Popen
from subprocess import Popen
process = None
@app.get("/command/{command}")
async def run_command(command: str):
global process
process = Popen([command]) # something long running
return {"run command"}
添加超时选项可能会很棘手,因为您不想等到它完成(您确实可以使用 wait_for 函数),而是在特定时间后终止进程。据我所知,最好的选择是安排负责杀死主要进程的其他进程。使用 asyncio 的代码可能如下所示:
@app.get("/command/{command}")
async def run_command(command: str):
global process
process = await asyncio.create_subprocess_exec(
command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
)
loop = asyncio.get_event_loop()
# We schedule here stop coroutine execution that runs after TIMEOUT seconds
loop.call_later(TIMEOUT, asyncio.create_task, stop(process.pid))
return {"run command"}
@app.get("/stop")
async def stop(pid=None):
global process
# We need to make sure we won't kill different process
if process and (pid is None or process.pid == pid):
process.kill()
process = None
return {"Stop"}