pst*_*tix 5 python asynchronous python-3.x python-asyncio aiohttp
致力于ThreadPoolExecutors
使用asyncio
和替换所有异步调用所使用的服务器查询工具的实现aiohttp
。由于网络调用是非阻塞IO,因此大多数过渡都是直接的,保存响应使我感到困惑。
我正在使用的所有示例,甚至是两个库的文档,都使用该示例asyncio.gather()
来收集所有等待的结果。就我而言,这些结果可以是许多GB范围内的文件,我不想将它们存储在内存中。
什么是解决此问题的合适方法?是否可以使用asyncio.as_completed()
然后:
for f in as_completed(aws):
earliest_result = await f
# Assumes `loop` defined under `if __name__` block outside coroutine
loop = get_event_loop()
# Run the blocking IO in an exectuor and write to file
_ = await loop.run_in_executor(None, save_result, earliest_result)
Run Code Online (Sandbox Code Playgroud)
这不是引入线程(假设ThreadPoolExecutor
默认情况下使用a ),从而使它成为异步多线程程序,而不是异步单线程程序吗?
此外,这是否可以确保earliest_result
在任何时候仅将1 写入文件?我不想await loop.run_in_executor(...)
运行该调用,然后出现另一个结果,我尝试运行到同一文件;我想可以限制一个信号量。
就我而言,这些结果可以是许多 GB 范围内的文件,并且我不想将它们存储在内存中。
如果我是正确的并且在您的代码中单个aws
意味着下载单个文件,您可能会面临以下问题:虽然as_completed
允许尽快将数据从 RAM 交换到 HDD,但所有aws
运行的并行存储每个数据(带有部分下载的文件的缓冲区) )同时在RAM中。
为了避免这种情况,您需要使用信号量来确保首先不会并行下载太多文件,从而防止 RAM 过度使用。
这是使用信号量的示例。
这是否会引入一个线程(假设我默认使用 ThreadPoolExecutor),从而使其成为异步、多线程程序而不是异步、单线程程序?
我不确定,我理解你的问题,但是是的,你的代码将使用线程,但只会save_result
在这些线程内执行。所有其他代码仍然在单个主线程中运行。这里没什么不好的。
此外,这是否可以确保任何时候只有 1 个 Early_result 被写入文件?
是的[*]。准确地说,await
您的代码片段最后一行的关键字将确保它:
_ = await loop.run_in_executor(None, save_result, earliest_result)
Run Code Online (Sandbox Code Playgroud)
您可以将其解读为:“开始run_in_executor
异步执行并在此行暂停执行流程,直到run_in_executor
完成并返回结果”。
f in as_completed(aws)
[*] 是的,如果您一开始就没有并行运行多个 for循环。
归档时间: |
|
查看次数: |
272 次 |
最近记录: |