- Python 教程
- Python 教程
- Python - 概述
- Python - 历史
- Python - 特性
- Python 与 C++
- Python - Hello World 程序
- Python - 应用领域
- Python 解释器及其模式
- Python - 环境设置
- Python - 虚拟环境
- Python - 基本语法
- Python - 变量
- Python - 数据类型
- Python - 类型转换
- Python - Unicode 系统
- Python - 文字
- Python - 运算符
- Python - 算术运算符
- Python - 比较运算符
- Python - 赋值运算符
- Python - 逻辑运算符
- Python - 按位运算符
- Python - 成员资格运算符
- Python - 身份运算符
- Python - 运算符优先级
- Python - 注释
- Python - 用户输入
- Python - 数字
- Python - 布尔值
- Python 控制语句
- Python - 控制流
- Python - 决策
- Python - if 语句
- Python - if-else 语句
- Python - 嵌套 if 语句
- Python - Match-Case 语句
- Python - 循环
- Python - For 循环
- Python for-else 循环
- Python - While 循环
- Python - break 语句
- Python - Continue 语句
- Python - pass 语句
- Python - 嵌套循环
- Python 函数和模块
- Python - 函数
- Python - 默认参数
- Python - 关键字参数
- Python - 仅关键字参数
- Python - 位置参数
- Python - 仅位置参数
- Python - 任意或可变长度参数
- Python - 变量范围
- Python - 函数注释
- Python - 模块
- Python - 内置函数
- Python 字符串
- Python - 字符串
- Python - 切片字符串
- Python - 修改字符串
- Python - 字符串连接
- Python - 字符串格式化
- Python - 转义字符
- Python - 字符串方法
- Python - 字符串练习
- Python 列表
- Python - 列表
- Python - 访问列表项
- Python - 更改列表项
- Python - 添加列表项
- Python - 删除列表项
- Python - 循环列表
- Python - 列表推导式
- Python - 排序列表
- Python - 复制列表
- Python - 联接列表
- Python - 列表方法
- Python - 列表练习
- Python 元组
- Python - 元组(Tuple )
- Python - 访问元组项
- Python - 更新元组
- Python - 解压缩元组项
- Python - 循环元组
- Python - 联接元组
- Python - 元组方法
- Python - 元组练习
- Python 集
- Python - 集(sets)
- Python - 访问 Set Items
- Python - 添加 Set Items
- Python - 删除 Set Items
- Python - 循环 Set Items
- Python - 联接 Sets
- Python - 复制 Set
- Python - Set 运算符
- Python - Set 方法
- Python - Set 的练习
- Python 字典
- Python - 字典
- Python - 访问字典项
- Python - 更改字典项
- Python - 添加字典项
- Python - 删除字典项
- Python - 字典视图对象
- Python - 循环字典
- Python - 复制字典
- Python - 嵌套字典
- Python - 字典方法
- Python - 字典练习
- Python 数组
- Python - 数组
- Python - 访问数组项
- Python - 添加数组项
- Python - 删除数组项
- Python - 循环数组
- Python - 复制数组
- Python - 反向数组
- Python - 对数组进行排序
- Python - 连接数组
- Python - 数组方法
- Python - 数组练习
- Python 文件处理
- Python - 文件处理
- Python - 写入文件
- Python - 读取文件
- Python - 重命名和删除文件
- Python - 目录
- Python - 文件方法
- Python OS 文件/目录方法
- Python - os.path 方法
- 面向对象编程
- Python - OOP 概念
- Python - 类和对象
- Python - 类属性
- Python - 类方法
- Python - 静态方法
- Python - 构造函数
- Python - 访问修饰符
- Python - 继承
- Python - 多态性
- Python - 方法覆盖
- Python - 方法重载
- Python - 动态绑定
- Python - 动态类型
- Python - 抽象
- Python - 封装
- Python - 接口
- Python - 软件包
- Python - 内部类
- Python - 匿名类和对象
- Python - 单例类
- Python - 包装类
- Python - 枚举
- Python - 反射
- Python 错误和异常
- Python - 语法错误
- Python - 异常处理
- Python - try-except 块
- Python - try-finally 块
- Python - 引发异常
- Python - 异常链接
- Python - 嵌套 try 块
- Python - 用户定义的异常
- Python - 日志记录
- Python - 断言
- Python - 内置异常
- Python 多线程
- Python - 多线程
- Python - 线程生命周期
- Python - 创建线程
- Python - 启动线程
- Python - 联接线程
- Python - 命名线程
- Python - 线程调度
- Python - 线程池
- Python - 主线程
- Python - 线程优先级
- Python - 守护程序线程
- Python - 同步线程
- Python 同步
- Python - 线程间通信
- Python - 线程死锁
- Python - 中断线程
- Python 网络
- Python - 网络编程
- Python - 套接字编程
- Python - URL 处理
- Python - 泛型
- Python 杂项
- Python - 日期和时间
- Python - math 模块
- Python - 迭代器
- Python - 生成器
- Python - 闭包(closures)
- Python - 装饰器( Decorators)
- Python - 递归
- Python - 正则表达式
- Python - PIP
- Python - 数据库访问
- Python - 弱引用
- Python - 序列化
- Python - 模板
- Python - 输出格式
- Python - 性能测量
- Python - 数据压缩
- Python - CGI 编程
- Python - XML 处理
- Python - GUI 编程
- Python - 命令行参数
- Python - 文档字符串
- Python - JSON
- Python - 发送电子邮件
- Python - 更多扩展
- Python - 工具/实用程序
- Python - 图形用户界面
- Python 高级概念
- Python - 抽象基类
- Python - 自定义异常
- Python - 高阶函数
- Python - 对象内部
- Python - 内存管理
- Python - 元类
- Python - 使用 Metaclasses 进行元编程
- Python - 模拟和存根
- Python - 猴子修补
- Python - 信号处理
- Python - 类型提示
- Python - 自动化教程
- Python - 人性化软件包
- Python - 上下文管理器
- Python - 协程
- Python - 描述符
- Python - 诊断和修复内存泄漏
- Python - 不可变数据结构
Python - 线程间通信
线程间通信是指在 Python 多线程程序中实现线程之间的通信和同步的过程。
通常,Python 中的线程在一个进程内共享相同的内存空间,这允许它们通过共享变量、对象和 threading 模块提供的专用同步机制来交换数据并协调其活动。
为了促进线程间通信,threading 模块提供了各种同步原语,如 Locks、Events、Conditions 和 Semaphores 对象。在本教程中,您将学习如何使用 Event 和 Condition 对象来提供多线程程序中线程之间的通信。
事件对象
Event 对象管理内部标志的状态,以便线程可以等待或设置。Event 对象提供控制此标志状态的方法,从而允许线程根据共享条件同步其活动。
该标志最初为 false,使用 set() 方法变为 true,并使用 clear() 方法重置为 false。wait() 方法会阻塞,直到标志为 true。
以下是 Event 对象的主要方法 -
- is_set():当且仅当内部标志为 true 时,返回 True。
- set():将 internal 标志设置为 true。所有等待它变为真的线程都将被唤醒。一旦标志为 true,调用 wait() 的线程将根本不会阻塞。
- clear():将内部标志重置为 false。随后,调用 wait() 的线程将阻塞,直到调用 set() 以再次将内部标志设置为 true。
- wait(timeout=None):阻止,直到内部标志为 true。如果 internal 标志在输入时为 true,则立即返回。否则,将阻塞,直到另一个线程调用 set() 将标志设置为 true,或者直到发生可选的超时。当 timeout 参数存在且不存在 None 时,它应该是一个浮点数,以秒为单位指定操作的超时时间。
例
以下代码尝试模拟由流量信号 GREEN 或 RED 状态控制的流量。
程序中有两个线程,针对两个不同的函数。signal_state() 函数会定期设置和重置指示信号从 GREEN 变为 RED 的事件。
traffic_flow() 函数等待事件被设置,并运行一个循环直到它保持设置状态。
from threading import Event, Thread
import time
terminate = False
def signal_state():
global terminate
while not terminate:
time.sleep(0.5)
print("Traffic Police Giving GREEN Signal")
event.set()
time.sleep(1)
print("Traffic Police Giving RED Signal")
event.clear()
def traffic_flow():
global terminate
num = 0
while num < 10 and not terminate:
print("Waiting for GREEN Signal")
event.wait()
print("GREEN Signal ... Traffic can move")
while event.is_set() and not terminate:
num += 1
print("Vehicle No:", num," Crossing the Signal")
time.sleep(1)
print("RED Signal ... Traffic has to wait")
event = Event()
t1 = Thread(target=signal_state)
t2 = Thread(target=traffic_flow)
t1.start()
t2.start()
# Terminate the threads after some time
time.sleep(5)
terminate = True
# join all threads to complete
t1.join()
t2.join()
print("Exiting Main Thread")
输出
在执行上述代码时,您将获得以下输出 -
Traffic Police Giving GREEN Signal
GREEN Signal ... Traffic can move
Vehicle No: 1 Crossing the Signal
Traffic Police Giving RED Signal
RED Signal ... Traffic has to wait
Waiting for GREEN Signal
Traffic Police Giving GREEN Signal
GREEN Signal ... Traffic can move
Vehicle No: 2 Crossing the Signal
Vehicle No: 3 Crossing the Signal
Traffic Police Giving RED Signal
Traffic Police Giving GREEN Signal
Vehicle No: 4 Crossing the Signal
Traffic Police Giving RED Signal
RED Signal ... Traffic has to wait
Traffic Police Giving GREEN Signal
Traffic Police Giving RED Signal
Exiting Main Thread
Condition 对象
Python 的 threading 模块中的 Condition 对象提供了更高级的同步机制。它允许线程在继续之前等待来自另一个线程的通知。Condition 对象始终与锁相关联,并提供在线程之间发送信号的机制。
以下是线程的语法。Condition() 类 −
threading.Condition(lock=None)
以下是 Condition 对象的关键方法 -
- acquire(*args):获取底层锁。此方法在底层锁上调用相应的方法;返回值是该方法返回的任何值。
- release():释放底层锁。此方法在底层锁上调用相应的方法;没有返回值。
- wait(timeout=None):此方法释放底层锁,然后阻塞,直到它被另一个线程中相同条件变量的 notify() 或 notify_all() 调用唤醒,或者直到发生可选的超时。一旦被唤醒或超时,它将重新获取锁并返回。
- wait_for(predicate, timeout=None):此实用程序方法可以重复调用 wait(),直到满足谓词或发生超时。返回值是谓词的最后一个返回值,如果方法超时,则计算结果为 False。
- notify(n=1):该方法最多唤醒 n 个等待 condition 变量的线程;如果没有线程等待,则为 no-op。
- notify_all():唤醒所有等待此条件的线程。此方法的作用类似于 notify(),但会唤醒所有等待的线程,而不是一个。如果在调用此方法时调用线程尚未获取锁,则会引发 RuntimeError。
例
此示例演示了使用 Python 的 threading 模块的 Condition 对象的一种简单形式的线程间通信。在这里,thread_a 和 thread_b 使用 Condition 对象进行通信,thread_a 会等待,直到收到来自 thread_b 的通知。thread_b 在通知 thread_a 之前休眠 2 秒钟,然后结束。
from threading import Condition, Thread
import time
c = Condition()
def thread_a():
print("Thread A started")
with c:
print("Thread A waiting for permission...")
c.wait()
print("Thread A got permission!")
print("Thread A finished")
def thread_b():
print("Thread B started")
with c:
time.sleep(2)
print("Notifying Thread A...")
c.notify()
print("Thread B finished")
Thread(target=thread_a).start()
Thread(target=thread_b).start()
输出
在执行上述代码时,您将获得以下输出 -
Thread A waiting for permission...
Thread B started
Notifying Thread A...
Thread B finished
Thread A got permission!
Thread A finished
例
下面是另一个代码,演示如何使用 Condition 对象提供线程之间的通信。在这种情况下,线程 t2 运行 taskB() 函数,线程 t1 运行 taskA() 函数。t1 线程获取条件并通知它。
此时,t2 线程处于等待状态。条件释放后,等待线程将继续使用通知函数生成的随机数。
from threading import Condition, Thread
import time
import random
numbers = []
def taskA(c):
for _ in range(5):
with c:
num = random.randint(1, 10)
print("Generated random number:", num)
numbers.append(num)
print("Notification issued")
c.notify()
time.sleep(0.3)
def taskB(c):
for i in range(5):
with c:
print("waiting for update")
while not numbers:
c.wait()
print("Obtained random number", 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("Done")
当您执行此代码时,它将生成以下输出 -
Generated random number: 2
Notification issued
Obtained random number 2
Generated random number: 5
Notification issued
waiting for update
Obtained random number 5
Generated random number: 1
Notification issued
waiting for update
Obtained random number 1
Generated random number: 9
Notification issued
waiting for update
Obtained random number 9
Generated random number: 2
Notification issued
waiting for update
Obtained random number 2
Done