如何在 Python 中惯用地结束 Asyncio 操作
How to idiomatically end an Asyncio Operation in Python
我正在编写代码,我有一个很长的 运行 shell 命令,它的输出被发送到磁盘。此命令将为每个文件生成数百 GB。我已经成功地编写了异步调用此命令的代码,并成功地产生了控制(等待)它来完成。
我还有一些代码可以在写入该文件时异步读取该文件,以便我可以处理其中包含的数据。我 运行 遇到的问题是,一旦 shell 命令完成,我找不到停止文件 reader 的方法。
我想我正在寻找某种中断,我可以在 shell 命令结束后传递到我的编写器函数中,我可以用它来告诉它关闭文件并结束事件循环。
这是我的作家功能。现在,它会永远运行,等待将新数据写入文件。
import asyncio
PERIOD = 0.5
async def readline(f):
while True:
data = f.readline()
if data:
return data
await asyncio.sleep(PERIOD)
async def read_zmap_file():
with open('/data/largefile.json'
, mode = 'r+t'
, encoding = 'utf-8'
) as f:
i = 0
while True:
line = await readline(f)
print('{:>10}: {!s}'.format(str(i), line.strip()))
i += 1
loop = asyncio.get_event_loop()
loop.run_until_complete(read_zmap_file())
loop.close()
如果我的方法不对,请告诉我。我对异步编程比较陌生。任何帮助将不胜感激。
所以,我会做类似的事情
reader = loop.create_task(read_zmap_file)
然后在管理 shell 进程的代码中,一旦 shell 进程退出,您可以执行
reader.cancel()
你可以做到
loop.run_until_complete(reader)
或者,您可以简单地在某处设置一个标志并在您的 while 语句中使用该标志。当一些更简单的东西起作用时,你不需要使用 asyncio 原语。
也就是说,我会研究您的 reader 可以避免周期性休眠的方法。如果您的 reader 能够跟上 shell 命令,我建议使用管道,因为管道可以与 select 一起使用(因此添加到事件循环中)。然后在你的 reader 中,如果你需要一个永久日志,你可以写入一个文件。我意识到避免周期性睡眠的讨论超出了这个问题的范围,我不想比我更详细,但你会询问如何最好地处理异步编程的提示。
我正在编写代码,我有一个很长的 运行 shell 命令,它的输出被发送到磁盘。此命令将为每个文件生成数百 GB。我已经成功地编写了异步调用此命令的代码,并成功地产生了控制(等待)它来完成。
我还有一些代码可以在写入该文件时异步读取该文件,以便我可以处理其中包含的数据。我 运行 遇到的问题是,一旦 shell 命令完成,我找不到停止文件 reader 的方法。
我想我正在寻找某种中断,我可以在 shell 命令结束后传递到我的编写器函数中,我可以用它来告诉它关闭文件并结束事件循环。
这是我的作家功能。现在,它会永远运行,等待将新数据写入文件。
import asyncio
PERIOD = 0.5
async def readline(f):
while True:
data = f.readline()
if data:
return data
await asyncio.sleep(PERIOD)
async def read_zmap_file():
with open('/data/largefile.json'
, mode = 'r+t'
, encoding = 'utf-8'
) as f:
i = 0
while True:
line = await readline(f)
print('{:>10}: {!s}'.format(str(i), line.strip()))
i += 1
loop = asyncio.get_event_loop()
loop.run_until_complete(read_zmap_file())
loop.close()
如果我的方法不对,请告诉我。我对异步编程比较陌生。任何帮助将不胜感激。
所以,我会做类似的事情
reader = loop.create_task(read_zmap_file)
然后在管理 shell 进程的代码中,一旦 shell 进程退出,您可以执行
reader.cancel()
你可以做到
loop.run_until_complete(reader)
或者,您可以简单地在某处设置一个标志并在您的 while 语句中使用该标志。当一些更简单的东西起作用时,你不需要使用 asyncio 原语。
也就是说,我会研究您的 reader 可以避免周期性休眠的方法。如果您的 reader 能够跟上 shell 命令,我建议使用管道,因为管道可以与 select 一起使用(因此添加到事件循环中)。然后在你的 reader 中,如果你需要一个永久日志,你可以写入一个文件。我意识到避免周期性睡眠的讨论超出了这个问题的范围,我不想比我更详细,但你会询问如何最好地处理异步编程的提示。