我试图通读asyncio示例,但未能找到最简单的示例(在我看来)。假设我有一个“正常”功能,需要1秒钟。我用time.sleep(1)
调用来模拟。如何以三个调用可以异步运行的方式包装该函数,以使总执行时间为1秒?
我可以通过使用线程来实现,但不能使用异步。
这里是一个例子:
import asyncio
import time
from threading import Thread
from datetime import datetime
from math import sqrt
def heavy_cpu(n):
print(f"{n} --> start: {datetime.now()}")
time.sleep(1)
# for i in range(5099999):
# _ = sqrt(i) * sqrt(i)
print(f"{n} --> finish: {datetime.now()}")
async def count(n):
await asyncio.sleep(0.0000001)
heavy_cpu(n)
async def main_async():
await asyncio.gather(count(1), count(2), count(3))
def test_async():
s = time.perf_counter()
asyncio.run(main_async())
elapsed = time.perf_counter() - s
print(f"asyncio executed in {elapsed:0.2f} seconds.")
# ========== asyncio vs threading =============
def main_thread():
threads = [Thread(target=heavy_cpu, args=(n,)) for n in range(1, 4)]
for t in threads:
t.start()
for t in threads:
t.join()
def test_thread():
s = time.perf_counter()
main_thread()
elapsed = time.perf_counter() - s
print(f"thread executed in {elapsed:0.2f} seconds.")
if __name__ == "__main__":
test_async()
test_thread()
输出:
1 --> start: 2020-05-12 18:28:53.513381
1 --> finish: 2020-05-12 18:28:54.517861
2 --> start: 2020-05-12 18:28:54.518162
2 --> finish: 2020-05-12 18:28:55.521757
3 --> start: 2020-05-12 18:28:55.521930
3 --> finish: 2020-05-12 18:28:56.522813
asyncio executed in 3.01 seconds.
1 --> start: 2020-05-12 18:28:56.523789
2 --> start: 2020-05-12 18:28:56.523943
3 --> start: 2020-05-12 18:28:56.524087
1 --> finish: 2020-05-12 18:28:57.5265992 --> finish: 2020-05-12 18:28:57.526689
3 --> finish: 2020-05-12 18:28:57.526849
thread executed in 1.00 seconds.
问题:为什么每个异步finish
步骤[1,2,3]都需要1秒钟?如何使它真正异步?
time.sleep
的方式(您清楚地知道asyncio.sleep
存在),那么异步就是这样工作的;任何不自愿(直接或间接通过await
将控制权返回给事件循环的任务)都将在其他任务[