我的用例是运行一些性能测试,所以我想创建一个应用程序,我运行4个任务4次,计算该任务的时间平均值,然后异步运行2个任务,计算平均值,然后异步运行4个任务,计算平均值,然后是8,依此类推。
但是,我无法像这样跑。当我这样做时,它似乎已经执行过所有任务,而且我错了很多次。
我尝试了一些点击和试用版,现在我在TypeError: An asyncio.Future, a coroutine or an awaitable is required
sys:1: RuntimeWarning: coroutine 'go' was never awaited
函数的loop.run_until_complete(asyncio.wait(asyncio.ensure_future(some_tasks)))
行run_tasks
获得了async def go(date):
pool = await aiopg.create_pool("**db connection**")
async with pool.acquire() as conn:
async with conn.cursor() as cur:
await cur.execute(""" some query """)
time.sleep(1)
ret = []
async for row in cur:
ret.append(row)
def date_range(date1, date2):
for n in range(int((date2 - date1).days)+1):
yield date1 + timedelta(n)
def run_tasks():
start_dt = datetime(2017, 8, 9)
end_dt = datetime(2017, 8, 10)
tasks = []
some_tasks = []
avg_time_run = []
for dt in date_range(start_dt, end_dt):
#tasks.append(asyncio.ensure_future(go(dt.strftime("%Y-%m-%d %H:%M:%S"))))
tasks.append(go(dt.strftime("%Y-%m-%d %H:%M:%S")))
i = 1
prev = 0
while i < 2: # i < 128
# Get i number of tasks from task list
for k in range(prev, i):
some_tasks.append(tasks[k])
prev = len(some_tasks)
time_run = []
for j in range(0, 4): # repeat task 4 times
start = time.time()
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(asyncio.ensure_future(some_tasks)))
# loop.close()
end = time.time()
diff = end - start
time_run.append(diff)
print("ith SomeTask: {}, {}".format(i, some_tasks))
print("Total time: {}".format(diff))
# get average of each task run 4 times
avg_time_run.append(sum(time_run) / float(len(time_run)))
i *= 2
return avg_time_run
print(run_tasks())
。
以下是我的代码:
asyncio.wait
一些提示将不胜感激。我应该在哪里等待{{1}}
答案 0 :(得分:2)
asyncio.ensure_future(some_tasks)
您将协程列表传递给asyncio.ensure_future
。正如您在documentation中看到的,这不是这个函数的工作原理:您应该传递单个协同程序来创建asyncio.Task。这就是为什么你得到TypeError
,然后你得到RuntimeWarning
,因为创建的go
协同程序不会因为以上所有而被等待。
在这种情况下你根本不需要asyncio.Task
,只需将协程列表传递给asyncio.wait
:
loop.run_until_complete(asyncio.wait(some_tasks))
更重要的一点是:
time.sleep(1)
你永远不应该在协同程序中执行它:它冻结你的事件循环(以及所有协同程序随处可见)。请阅读this answer,了解asyncio的工作原理。
如果你想在协同程序中睡一段时间,请使用asyncio.sleep:
await asyncio.sleep(1)
答案 1 :(得分:0)
回答代码:
async def run(date): // for adopt, check above go() function
conn = await asyncpg.connect("db connections")
values = await conn.fetch("""some query """)
await asyncio.sleep(1)
await conn.close()
def date_range(date1, date2):
for n in range(int((date2 - date1).days)+1):
yield date1 + timedelta(n)
def run_tasks():
start_dt = datetime(2017, 8, 9)
end_dt = datetime(2017, 8, 10)
tasks = []
avg_time_run = []
i = 1
while i < 9: # num of tasks incremented
time_run = []
start = time.time()
loop = asyncio.get_event_loop()
for dt in date_range(start_dt, end_dt):
if len(tasks) < i:
print(dt)
tasks.append(asyncio.ensure_future(run(dt.strftime("%Y-%m-%d %H:%M:%S"))))
if len(tasks) == i:
for j in range(0, 4): # repeat task 4 times
print("J counter: {}".format(j))
loop.run_until_complete(asyncio.wait(tasks))
end = time.time()
diff = end - start
time_run.append(diff)
print("Num of Tasks executing: {}, {}".format(i, tasks))
print("Task len: {}".format(len(tasks)))
print("Total time: {}".format(diff))
# get average of each task run 4 times
avg_time_run.append(sum(time_run) / float(len(time_run)))
start_dt = end_dt + timedelta(days=1)
end_dt = end_dt + timedelta(days=(i * 2 - i))
i *= 2
print(start_dt)
print(end_dt)
#loop.close()
return avg_time_run
print(run_tasks())