Python线程间通信精通:Event与Condition同步机制深度解析
线程间通信指Python多线程程序中线程间通信与同步。Python线程共享进程内存空间,可通过共享变量、对象及threading模块同步原语(锁、Event、Condition、Semaphore)交换数据协调活动。
本教程重点讲解Event和Condition对象实现线程间通信。
Event对象
Event对象管理内部标志状态,线程可等待或设置。提供方法控制标志,让线程基于共享条件同步。
标志初始为false,set()置true,clear()重置false,wait()阻塞至标志为true。
Event关键方法
- is_set():标志为true返回True
- set():置标志true,唤醒所有等待线程。标志为true后调用
wait()不阻塞 - clear():重置标志false,后续
wait()阻塞直至再次set() - wait(timeout=None):阻塞至标志true。入口即true立即返回;否则阻塞直到他线程
set()或超时。timeout为秒数浮点数
示例:交通信号灯模拟
两线程模拟交通流受信号灯控制(绿/红)。signal_state()周期性设置/清除事件模拟信号变换;traffic_flow()等待事件置位,绿灯时循环放行车辆。
from threading import Event, Thread
import time
terminate = False
def signal_state():
global terminate
while not terminate:
time.sleep(0.5)
print("交通警察发绿灯信号")
event.set()
time.sleep(1)
print("交通警察发红灯信号")
event.clear()
def traffic_flow():
global terminate
num = 0
while num < 10 and not terminate:
print("等待绿灯信号")
event.wait()
print("绿灯...车辆可通行")
while event.is_set() and not terminate:
num += 1
print("车辆编号:", num, "通过路口")
time.sleep(1)
print("红灯...车辆须等待")
event = Event()
t1 = Thread(target=signal_state)
t2 = Thread(target=traffic_flow)
t1.start(); t2.start()
time.sleep(5)
terminate = True
t1.join(); t2.join()
print("主线程退出")
输出
等待绿灯信号 交通警察发绿灯信号 绿灯...车辆可通行 车辆编号: 1 通过路口 交通警察发红灯信号 红灯...车辆须等待 等待绿灯信号 交通警察发绿灯信号 绿灯...车辆可通行 车辆编号: 2 通过路口 车辆编号: 3 通过路口 交通警察发红灯信号 交通警察发绿灯信号 车辆编号: 4 通过路口 交通警察发红灯信号 红灯...车辆须等待 交通警察发绿灯信号 交通警察发红灯信号 主线程退出
Condition对象
threading.Condition提供更高级同步机制。允许线程等待另一线程通知后继续。Condition总关联一把锁,提供线程间信令机制。
语法
threading.Condition(lock=None)
Condition关键方法
- acquire(*args):获取底层锁
- release():释放底层锁
- wait(timeout=None):释放锁并阻塞,直至他线程
notify()/notify_all()唤醒或超时,醒来后重获锁返回 - wait_for(predicate, timeout=None):反复
wait()直到谓词满足或超时 - notify(n=1):唤醒至多n个等待线程,无等待者则无操作
- notify_all():唤醒所有等待线程。调用时未获锁抛
RuntimeError
示例1:基础通知等待
thread_a等待thread_b通知。thread_b睡2秒后通知并结束。
from threading import Condition, Thread
import time
c = Condition()
def thread_a():
print("线程A启动")
with c:
print("线程A等待许可...")
c.wait()
print("线程A获许可!")
print("线程A结束")
def thread_b():
print("线程B启动")
with c:
time.sleep(2)
print("通知线程A...")
c.notify()
print("线程B结束")
Thread(target=thread_a).start()
Thread(target=thread_b).start()
输出:
线程A启动 线程A等待许可... 线程B启动 通知线程A... 线程B结束 线程A获许可! 线程A结束
示例2:生产者-消费者模式
t2运行taskA()生产随机数并通知;t1运行taskB()等待消费。t1获取条件等待,t2生产后通知,t1消费弹出数值。
from threading import Condition, Thread
import time, random
numbers = []
def taskA(c):
for _ in range(5):
with c:
num = random.randint(1, 10)
print("生成随机数:", num)
numbers.append(num)
print("发出通知")
c.notify()
time.sleep(0.3)
def taskB(c):
for i in range(5):
with c:
print("等待更新")
while not numbers:
c.wait()
print("获取随机数", numbers.pop())
time.sleep(0.3)
c = Condition()
t1 = Thread(target=taskB, args=(c,))
t2 = Thread(target=taskA, args=(c,))
t1.start(); t2.start()
t1.join(); t2.join()
print("完成")
输出:
等待更新 生成随机数: 2 发出通知 获取随机数 2 生成随机数: 5 发出通知 等待更新 获取随机数 5 生成随机数: 1 发出通知 等待更新 获取随机数 1 生成随机数: 9 发出通知 等待更新 获取随机数 9 生成随机数: 2 发出通知 等待更新 获取随机数 2 完成
Python
- Python C 扩展开发指南:构建高性能原生模块
- Python 语言概览:高级、可读、交互式与面向对象
- Python 与 Selenium 自动化 Facebook 登录:分步指南
- Python 列表去重完全指南:七种方法与最佳实践
- Python XML 处理指南:实现跨平台数据互操作
- Python命名空间与变量作用域:理解名称、绑定与作用域
- Python 列表删除元素全攻略:remove、pop、clear 与 del 详解
- Windows 安装 Python 与 PyCharm 完整图文教程
- Python 轻松获取当前时间与时区数据
- 精通Python函数参数:位置、关键字与默认参数
- Python format() 字符串格式化完全指南:占位符、格式化规范、类与字典应用
- Python 优雅交换两变量:无需临时变量的一行代码