python - 使用 asyncio 在一个时间间隔内运行命令并在之后终止它
问题描述
我正在执行一个 shell 命令os.system()
。我计划运行它 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
我们的子进程(因为这不是自动完成的)。
推荐阅读
- javascript - React 和 Javascript 通过与之前的状态进行比较从状态中获取更新/编辑的值
- c# - 尝试激活“X.Controllers.Events.JsonSerializer”时无法解析“Newtonsoft.Json.JsonSerializerSettings”类型的服务
- flutter - 如何在颤动中发送文件
- flutter - Webview Flutter 无法更改 URL
- c# - 如果 PageSize 为 0,Linq 获取所有记录
- reactjs - React JS - 运行 npm add gh-pages 命令时出现警告
- c# - WPF 编程,如何将事件移动到另一个类(外部)
- lua - 用于 lua 表的类似 JS 对象的函数
- javascript - Get changes based on uploaded time from firebase
- android - NullPointerException 尝试获取空数组的长度 [react-native]