【问题标题】:aiohttp/asyncio unexcepted running sequence resultsaiohttp/asyncio 无异常运行序列结果
【发布时间】:2021-08-20 07:51:06
【问题描述】:
import asyncio
import time

import aiohttp

now = lambda :time.time()
async def do_some_work(x):
    print("waiting:",x)
    await asyncio.sleep(x)
    return f"Web is ok"

start = now()
coroutine = do_some_work(2) # a future
loop = asyncio.get_event_loop()

task = asyncio.ensure_future(coroutine)
loop.run_until_complete(task)
print("In the process of accessing web") # I want this run first before sleep
print("Task ret:", task.result())
print("Time:", now() - start)

这些是我的结果和问题:

  1. python3 test_aio_return.py
  2. 等待:2(睡在这里)
  3. 正在访问网络。
  4. 任务恢复:Web is ok。我希望它在这一步休眠,因为我正在使用协程这一行的结果。
  5. 时间:2.0011699199676514

【问题讨论】:

  • 问题是什么?你应该更好地描述问题。
  • 如果你想在sleep()之前运行print(...),那么把它放在loop.run...之前。或者您应该将其作为另一个任务运行。因为run_until_complete 阻塞了其他代码until complete tasks
  • 抱歉,我没有明确提出我的问题。是的,我确实希望我的printsleep 之前运行,但我想让sleep 先运行,然后当协程处于睡眠状态时,该进程将被授予主线程,然后它转到print("In the process of accessing web") 和我只是想知道协程在睡眠时会将处理器授予主线程吗?
  • 当您使用coroutine 时,您还必须在coroutine 中运行其他元素 - 因为run_until_complete 一直在运行,它无法运行其他代码。

标签: python python-asyncio aiohttp


【解决方案1】:

如果你运行一个coroutine(或者更确切地说是Task),那么主线程正在运行loop,这会阻塞这个线程和你必须在其他coroutine(或者更确切地说Task)中运行的其他代码。

类似这样的:

import asyncio
import time

async def do_some_work(x):
    print("[do_some_work] waiting:", x)
    await asyncio.sleep(x)
    print("[do_some_work] end")
    return "Web is ok"

async def other():
    #print("[other] In the process of accessing web")
    for x in range(10):
        print("[other]", x, "In the process of accessing web")
        await asyncio.sleep(0.5)

async def main():
    # create two tasks
    #task1 = asyncio.ensure_future(do_some_work(5))
    #task2 = asyncio.ensure_future(other())
    task1 = asyncio.create_task(do_some_work(5))
    task2 = asyncio.create_task(other())

    # run both tasks at the same time
    #await asyncio.gather(task1, task2)
    #await asyncio.wait([task1, task2])
    await task1
    await task2

    return task1.result()

# --- main ---

now = lambda:time.time()

start = now()

print('start loop')
#loop = asyncio.get_event_loop()
#result = loop.run_until_complete(main())
result = asyncio.run(main())
print('stop loop')

print("result:", result)

end = now()

print("Time:", end - start)

它适用于gather(task1, task2)wait([task1, task2]) 或直接task1, task2


编辑:

如果你使用coroutines而不是Tasks,它将不会同时运行

async def main():
    # create two coroutines
    task1 = do_some_work(5)
    task2 = other()

    # run coroutines one-after-another
    await task1
    await task2

    return task1.result()

它需要gather(task1, task2)wait([task1, task2]) 来创建Tasks

async def main():
    task1 = do_some_work(5)
    task2 = other()

    results = await asyncio.gather(task1, task2)
    #print(results)

    return results[0]

【讨论】:

    猜你喜欢
    • 2021-06-17
    • 1970-01-01
    • 1970-01-01
    • 2020-11-28
    • 2018-12-07
    • 1970-01-01
    相关资源
    最近更新 更多