❝Python入门第三十二课,主要是学习了multiprocessing.Value的用法,这是 Python 多进程编程中用于在进程间共享单个值(如整数、浮点数、字符等)的工具。
一、基本概念
Value 是一个可共享的、类型化的内存对象,允许多个进程访问同一块内存区域。它与普通变量的区别在于:
Value 对象存储在共享内存中,所有进程可以看到它的变化。
二、创建语法
from multiprocessing import Valuev = Value(typecode_or_type, initial_value, lock=True)
参数说明:
| |
|---|
typecode_or_type | 类型码(如 'i' 表示有符号整型)或 Python 类型(如 ctypes.c_int) |
initial_value | |
lock | 是否自动加锁(默认 True),设为 False 时需手动同步 |
常用类型码:
| | | |
|---|
'i' | | | |
'I' | | | |
'l' | | | |
'L' | | | |
'f' | | | |
'd' | | | |
'c' | | | |
'b' | | | |
'B' | | | |
三、基本使用
from multiprocessing import Value, Processdefworker(num): num.value += 10# 修改共享值 print(f'子进程修改后的值: {num.value}')if __name__ == '__main__':# 创建共享整数,初始值0 shared_number = Value('i', 0) print(f'初始值:{shared_number.value}') p = Process(target=worker, args=(shared_number,)) p.start() p.join() print(f'主进程看到的值:{shared_number.value}')
上面的代码运行结果如下:
初始值:0子进程修改后的值: 10主进程看到的值:10
四、锁机制(重要)
默认情况下 lock=True,Value 内部使用递归锁(RLock)保护读写操作。这样可以保证 += 这类“读-改-写”操作的原子性。
不安全示例(手动关闭锁):
counter = Value('i', 0, lock=False) # 无锁defincrement():for _ in range(1000): counter.value += 1# 启动多个进程 -> 结果可能小于期望值(竞态条件)
安全写法(使用内置锁或自定义锁):
counter = Value('i', 0) # lock=True(默认)defincrement():for _ in range(1000): counter.value += 1# 内部自动加锁
或者显式使用锁对象:
counter = Value('i', 0, lock=True)with counter.get_lock(): # 获取锁 counter.value += 1
五、与普通变量的区别演示
from multiprocessing import Process, Valuedefmodify_shared(val): val.value = 42defmodify_normal(num): num = 42# 只修改局部变量,不影响主进程if __name__ == '__main__':# 共享版本 shared = Value('i', 0) p1 = Process(target=modify_shared, args=(shared,)) p1.start() p1.join() print(f'共享版本:{shared.value}')# 普通版本 normal = 0 p2 = Process(target=modify_normal, args=(normal,)) p2.start() p2.join() print(f'普通版本:{normal}')
上面的代运行结果如下:
共享版本:42普通版本:0
六、常用属性与方法
| |
|---|
obj.value | |
obj.get_lock() | |
obj.acquire() | |
七、实际应用场景
累加计数器:多个进程统计总处理量。
from multiprocessing import Process, Valuedefworker(counter, lock):for _ in range(100):with lock: counter.value += 1# 显示加锁更安全if __name__ == '__main__': counter = Value('i', 0) lock = counter.get_lock() processes = [Process(target=worker, args=(counter, lock)) for _ in range(5)]for p in processes: p.start()for p in processes: p.join() print(counter.value)
上面的代码运行结果:500。
其他应用场景:
- 状态标志:主进程设置
running.value = False 通知子进程停止。 - 简单共享配置:如
debug_mode = Value('b', 0)。
八、注意事项
Value 只适合共享单个数值或小对象。共享大数据应使用 multiprocessing.Array 或 shared_memory。- 如果共享复杂对象(如字典、列表),建议使用
multiprocessing.Manager,尽管性能稍差但使用方便。 - 修改字符串:
Value('u', 'hello')(Python 3 中不推荐,可用 Array)。 - 进程退出后,
Value 对象依然存活(如果主进程还持有引用),手动删除可调用 del v。
总结
Value 是进程间共享单个变量的便捷工具,默认带锁保证线程安全。
对于复杂数据或不需要极致性能的场景,Manager 可能是更简单的选择。
但在高性能计数、标志位等场景下,Value 非常高效。