在一个时间间隔内使用 asyncio to 运行 命令并在之后终止它
Using asyncio to run command in a time interval and terminate it afterwards
我正在执行 os.system()
的 shell 命令。我计划 运行 它 1 秒,然后在超过时间时终止它。这是我作为测试尝试的内容。
import os, time, asyncio
async def cmd():
os.system("my.py > my.txt") # this processes longer than 1 second
@asyncio.coroutine
def run():
try:
yield from asyncio.wait_for(cmd(), 1) # this should excute for more than 1 sec, and hence raise TimeoutError
print("A")
except asyncio.TimeoutError:
os.system("killall python")
print("B")
asyncio.run(run())
但结果总是“A”,txt 是 my.py 写的。
我也试过:
import os, time, asyncio
async def cmd():
os.system("my.py > my.txt") # longer than 1 sec
async def run():
try:
await asyncio.wait_for(cmd(), 1) # should raise TimeoutError
print("A")
except asyncio.TimeoutError:
os.system("killall python")
print("B")
asyncio.run(run())
结果相同。
代码有什么问题?我对 asyncio 很陌生,以前从未使用过它。提前致谢。 wait_for
不会自动停止转换很可能不是问题,因为我在第二部分有一个 killall python
事实上,wait_for 函数永远不会引发超时错误,那是问题。
os.system
是阻塞操作,所以和asyncio
玩起来不太好。每当您使用 asyncio
时,所有“更长”的操作都需要是异步的,否则您首先会失去使用 asyncio
的所有好处。
import asyncio
async def cmd():
try:
proc = await asyncio.create_subprocess_shell(
"sleep 2 && date > my.txt",
shell=True,
stdout=asyncio.subprocess.DEVNULL,
stderr=asyncio.subprocess.DEVNULL)
await proc.communicate()
except asyncio.CancelledError:
proc.terminate()
print("X")
async def run():
try:
await asyncio.wait_for(cmd(), 1)
print("A")
except asyncio.TimeoutError:
print("B")
asyncio.run(run())
正如@dim 在评论中提到的,asyncio.create_subprocess_exec
将异步启动外部命令。 wait_for
实际上会引发两个异常:等待代码中的 TimeoutError
和等待代码中的 CancelledError
。我们可以使用后者来实现操作被取消,并terminate
或kill
我们的子进程(因为这不是自动完成的)。
我正在执行 os.system()
的 shell 命令。我计划 运行 它 1 秒,然后在超过时间时终止它。这是我作为测试尝试的内容。
import os, time, asyncio
async def cmd():
os.system("my.py > my.txt") # this processes longer than 1 second
@asyncio.coroutine
def run():
try:
yield from asyncio.wait_for(cmd(), 1) # this should excute for more than 1 sec, and hence raise TimeoutError
print("A")
except asyncio.TimeoutError:
os.system("killall python")
print("B")
asyncio.run(run())
但结果总是“A”,txt 是 my.py 写的。
我也试过:
import os, time, asyncio
async def cmd():
os.system("my.py > my.txt") # longer than 1 sec
async def run():
try:
await asyncio.wait_for(cmd(), 1) # should raise TimeoutError
print("A")
except asyncio.TimeoutError:
os.system("killall python")
print("B")
asyncio.run(run())
结果相同。
代码有什么问题?我对 asyncio 很陌生,以前从未使用过它。提前致谢。 wait_for
不会自动停止转换很可能不是问题,因为我在第二部分有一个 killall python
事实上,wait_for 函数永远不会引发超时错误,那是问题。
os.system
是阻塞操作,所以和asyncio
玩起来不太好。每当您使用 asyncio
时,所有“更长”的操作都需要是异步的,否则您首先会失去使用 asyncio
的所有好处。
import asyncio
async def cmd():
try:
proc = await asyncio.create_subprocess_shell(
"sleep 2 && date > my.txt",
shell=True,
stdout=asyncio.subprocess.DEVNULL,
stderr=asyncio.subprocess.DEVNULL)
await proc.communicate()
except asyncio.CancelledError:
proc.terminate()
print("X")
async def run():
try:
await asyncio.wait_for(cmd(), 1)
print("A")
except asyncio.TimeoutError:
print("B")
asyncio.run(run())
正如@dim 在评论中提到的,asyncio.create_subprocess_exec
将异步启动外部命令。 wait_for
实际上会引发两个异常:等待代码中的 TimeoutError
和等待代码中的 CancelledError
。我们可以使用后者来实现操作被取消,并terminate
或kill
我们的子进程(因为这不是自动完成的)。