python知识

明廷盛 嘻嘻😁

线程

问题:两个人同时改一个变量

# 一个银行账户
balance = 100

# 取款函数
def withdraw(amount):
global balance
if balance >= amount: # ① 检查够不够
balance -= amount # ② 扣钱

正常情况(一个人操作):

你取 60:① 检查 100 >= 60 ✓ → ② balance=40 → 余额 40

出问题的情况(两个人同时操作):

线程A(取60)              线程B(取80)

① 检查 100>=60 ✓
① 检查 100>=80 ✓ ← B 看到的还是 100!
② balance = 100-60 = 40 ← A 改了
② balance = 100-80 = 20 ← B 用旧值覆盖了 A 的修改

最终余额 20,但明明取了 60+80=140,应该报错的。这就是多线程同时改一个变量的风险


解决方案:锁(Lock)

锁就像厕所门,一次只能一个人进去。

lock = Lock()     # 创建一把锁
balance = 100

def withdraw(amount):
global balance
lock.acquire() # 🔒 锁门(别人等着)
if balance >= amount:
balance -= amount
lock.release() # 🔓 开门(下一个人可以进)

加锁后的执行

线程A                       线程B

lock.acquire() 🔒 拿到锁
① 检查 100>=60 ✓ lock.acquire() 🚫 等...(A 占着)
② balance=40 🚫 还在等...
lock.release() 🔓 释放锁
lock.acquire() 🔒 拿到锁了!
① 检查 40>=80 ✗ 钱不够,不扣
lock.release() 🔓

B 现在看到的是 A 改完后的 40,正确拒绝。


with lock: 是什么?

就是上面 acquire/release自动版本

# 手动版(繁琐,容易忘 release)
lock.acquire()
# ... 你的代码 ...
lock.release()

# with 版(自动,永远不会忘释放)
with lock:
# ... 你的代码 ...

with 保证:不管代码块里发生了什么(正常结束、提前 return、甚至报错崩溃),锁一定会被释放

对比:

# 手动版 — 如果这行报错,下面 release 永远不执行 → 死锁
lock.acquire()
data = 1 / 0 # 报错!
lock.release() # 永远跑不到这行 ← BUG

# with 版 — 报错也会自动释放
with lock:
data = 1 / 0 # 报错!但 with 自动调 release(),锁不会死

回到你的代码

def new_round(self):
with self.lock: # 🔒 锁住
self.pending.clear() # 清空旧数据
self.running = True # 标记运行中
self.round += 1 # 轮号+1
return self.round # 返回新轮号
# 🔓 with 结束,自动解锁

这三步(清空 + 标记 + 递增)必须一次做完,中间不能被打断。如果不用 with

线程A(new_round)              线程B(append)

pending.clear() ✅
round_id=3 ≠ self.round=2 → 不写入 ✅ 正常
running = True ✅
round_id=3 ≠ self.round=2 → 不写入 ✅ 正常
self.round += 1 → round=3
round_id=3 == self.round=3 → 写入!❌
(但 pending 已经在上一行被 clear 了,
这一瞬间 running=True 但 pending=空)

加了 with,B 的 append 要么在 A 完全改完之前执行(看到旧 round),要么在完全改完之后执行(看到新 round),不会看到”改了一半”的中间状态。

  • Title: python知识
  • Author: 明廷盛
  • Created at : 2026-07-25 07:56:17
  • Updated at : 2026-07-25 15:51:00
  • Link: https://blog.20040424.xyz/2026/07/25/⏸️VibeCoding/python知识/
  • License: All Rights Reserved © 明廷盛