我试图离开线程并开始使用异步。我试图写一些简单的东西,以便对异步更加适应。由于某种原因,我的异步代码未执行异步操作。
我在线程中重写了相同的代码,与异步代码不同,它可以快速并发地工作。
正常代码
import time
import random
def display(x: int) -> None:
time.sleep(random.randint(1, 8))
print(x)
def main():
for i in range(10):
display(i)
if __name__ == '__main__':
main()
输出
0
1
2
3
4
5
6
7
8
9
异步代码
import time
import random
import asyncio
async def display(x: int) -> None:
await asyncio.sleep(random.randint(1, 8))
print(x)
async def main():
for i in range(10):
await display(i)
if __name__ == '__main__':
event_loop = asyncio.get_event_loop()
event_loop.run_until_complete(main())
event_loop.close()
输出
0
1
2
3
4
5
6
7
8
9
线程代码
import time
import random
import threading
def display(x: int) -> None:
time.sleep(random.randint(1, 8))
print(x)
def main():
threads = []
for i in range(10):
t = threading.Thread(target=display, args=[i])
threads.append(t)
t.start()
for t in threads:
t.join()
if __name__ == '__main__':
main()
输出
5
9
3
0
4
2
1
8
6
7
答案 0 :(得分:1)
await display(i)
使用参数display
运行i
,该参数返回 awaitable 。然后,您立即使用await
等待呼叫,从而阻止该呼叫。
如果要一起计划所有计划,然后在最后等待,则需要将等待项收集到列表中,然后立即等待所有计划。
import time
import random
import asyncio
async def display(x: int) -> None:
await asyncio.sleep(random.randint(1, 8)/10)
print(x)
async def main():
awaitables = []
for i in range(10):
awaitables.append(display(i))
await asyncio.wait(awaitables)
if __name__ == '__main__':
event_loop = asyncio.get_event_loop()
event_loop.run_until_complete(main())
event_loop.close()
是的,因为否则肯定会指出来,您也可以将其写在列表理解中:
async def main():
await asyncio.wait([display(i) for i in range(10)])
更多说明:
我确定您知道,但是无论如何我都认为很重要。该代码运行异步,但不是 parallel 。使用async
或threading.Thread
运行多个计算繁重的函数仍然只能在一个CPU内核上运行它们,而没有任何加速。 Python解释器是单线程的。