在我的项目中,我有一个列表来执行我执行的任务。
loop.run_until_complete(tasks)
然而,有无数的任务,所以目前我分批执行它们。基本上,我有这个:
def get_results(tasks):
return [result for result in loop.run_until_complete(handle_tasks(tasks))]
while True:
tasks = get_tasks()
results = get_results(tasks)
我得到了许多任务,我吃了一个常规函数,它使用一个循环来异步执行这些任务并返回结果。
这种方法有效,但我相信它可以改进。
我想做一些任务充值而不是完成批量任务。
这样的事情:
while True:
if current_tasks < max_tasks:
new_tasks = get_tasks(max_tasks - current_tasks)
add_tasks(new_tasks)
current_tasks, results = stats_and_results()
我很感激有关如何解决这个问题的任何想法。
谢谢!
答案 0 :(得分:2)
我们遇到了类似的问题,最后编写了一个小的“Pool”包装器,它接受了作业并使用预定义的并发运行它们。
import asyncio
import sys
class Pool:
def __init__(self, concurrency):
self._sem = asyncio.BoundedSemaphore(concurrency)
self.jobs = []
async def __aenter__(self):
return self
async def __aexit__(self, *_):
if len(self.jobs) > 0:
await asyncio.wait(self.jobs)
def put(self, coro):
assert asyncio.iscoroutine(coro)
async def wrapped():
async with self._sem:
await coro
fut = asyncio.ensure_future(wrapped())
self.jobs.append(fut)
async def __aiter__(self):
return self
async def __anext__(self):
try:
coro = self.jobs.pop(0)
except IndexError:
raise StopAsyncIteration()
else:
return await coro
然后您可以这样使用它:
async def main():
pool = Pool(10)
for task in get_tasks():
pool.put(task)
async for result in pool:
print('got', result)
这将安排所有任务,同时运行最多10个任务并返回结果,因为它们来到main()协程