想象你经营着一家数字餐厅:
import asyncio
async def chef(order):
await asyncio.sleep(1) # 烹饪时间
return f"{order}做好了"
async def waiter():
tasks = [chef(n) for n in range(5)]
return await asyncio.gather(*tasks)
print(asyncio.run(waiter())) # 同时处理5个订单
这不是普通的函数调用,而是并发编程的魔法世界。我们将探索三种分身术:线程、进程、协程。
一、线程:共享记忆的双胞胎
线程陷阱演示:
import threading
counter = 0
def add():
global counter
for _ in range(100000):
counter += 1
threads = [threading.Thread(target=add) for _ in range(10)]
[t.start() for t in threads]
[t.join() for t in threads]
print(counter) # 可能不是1000000!
解决方案:
from threading import Lock
lock = Lock()
def safe_add():
global counter
for _ in range(100000):
with lo