【发布时间】:2021-01-08 16:37:48
【问题描述】:
我在 Python 中开发了一个简单的脚本,使用 asyncio 和 tasks 同时对多个目标执行一些随机工作。我有几个关于并发和 Python 解释器对任务管理的优化的问题,因为我对并发编程有点陌生。
我的主要问题是,Python 在什么时候决定同时运行任务?这是 Python 解释器此时进行的优化吗?或者我应该使用 threads 或 futures 显式编写根据代码?
非常感谢任何指向有趣的帖子、经验或文档的指针。
我附上了几个代码 sn-ps 用于比较它们:
# A Python3 example that uses tasks for concurrency
import asyncio
import time
async def factorial(name, number):
f = 1
for i in range(2, number + 1):
#print(f"Task {name}: Compute factorial({i})...")
await asyncio.sleep(1)
f *= i
#print(f"Task {name}: factorial({number}) = {f}")
async def main():
print(f"started main at {time.strftime('%X')}")
# Schedule three calls *concurrently*:
await asyncio.gather(
factorial("A", 2),
factorial("B", 3),
factorial("C", 4),
)
print(f"started main at {time.strftime('%X')}")
asyncio.run(main())
# A second example using threads.
import asyncio
import time
async def factorial(name, number):
f = 1
for i in range(2, number + 1):
#print(f"Task {name}: Compute factorial({i})...")
await asyncio.sleep(1)
f *= i
#print(f"Task {name}: factorial({number}) = {f}")
async def main():
print(f"started main at {time.strftime('%X')}")
try:
await asyncio.gather(
asyncio.to_thread(await factorial("A", 2)),
asyncio.to_thread(await factorial("B", 3)),
asyncio.to_thread(await factorial("C", 4)),
)
except:
print("Main routine finished.")
print(f"started main at {time.strftime('%X')}")
asyncio.run(main())
谢谢!
【问题讨论】:
-
GIL 对异步任务没有任何影响,因为它们无论如何都在单个线程中运行。即使你在这里使用线程来完成这些任务,大部分时间都在
sleep,你也不会注意到 GIL 引起的任何问题。 -
老实说,这主要是模拟高消耗任务的虚拟函数(我可能需要在帖子中添加)。我的问题很好......如果我动态生成大量这些任务...... Python 解释器是否会选择将这些任务视为线程?
标签: python python-3.x python-asyncio gil