python快速入门学习笔记(进阶篇)三十二:进程(四)多进程共享内存对象 Value

  • 原创
  • 作者:程序员三丰
  • 发布时间:2026-05-30 22:24
  • 浏览量:3
Python入门第三十二课,主要是学习了multiprocessing.Value的用法,这是 Python 多进程编程中用于在进程间共享单个值(如整数、浮点数、字符等)的工具。

一、基本概念

Value 是一个可共享的、类型化的内存对象,允许多个进程访问同一块内存区域。它与普通变量的区别在于:

  • 普通变量在每个进程中独立复制,互不干扰。
  • Value 对象存储在共享内存中,所有进程可以看到它的变化。

二、创建语法

from multiprocessing import Value

v = Value(typecode_or_type, initial_value, lock=True)

参数说明:

参数 说明
typecode_or_type 类型码(如 'i' 表示有符号整型)或 Python 类型(如 ctypes.c_int
initial_value 初始值
lock 是否自动加锁(默认 True),设为 False 时需手动同步

常用类型码:

类型码 C类型 Python类型 大小
'i' signed int int 4字节
'I' unsigned int int 4字节
'l' signed long int 4/8
'L' unsigned long int 4/8
'f' float float 4字节
'd' double float 8字节
'c' char str (单字符) 1字节
'b' signed char int 1字节
'B' unsigned char int 1字节

三、基本使用

from multiprocessing import Value, Process

def worker(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=TrueValue 内部使用递归锁(RLock)保护读写操作。这样可以保证 += 这类“读-改-写”操作的原子性。

不安全示例(手动关闭锁):

counter = Value('i', 0, lock=False)   # 无锁

def increment():
    for _ in range(1000):
        counter.value += 1

# 启动多个进程 -> 结果可能小于期望值(竞态条件)

安全写法(使用内置锁或自定义锁):

counter = Value('i', 0)   # lock=True(默认)

def increment():
    for _ in range(1000):
        counter.value += 1   # 内部自动加锁

或者显式使用锁对象:

counter = Value('i', 0, lock=True)
with counter.get_lock():    # 获取锁
    counter.value += 1

五、与普通变量的区别演示

from multiprocessing import Process, Value

def modify_shared(val):
    val.value = 42


def modify_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() 返回锁对象(用于 with 语句)
obj.acquire() / obj.release() 手动加锁/解锁(不推荐,建议用 with

七、实际应用场景

累加计数器:多个进程统计总处理量。

from multiprocessing import Process, Value

def worker(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.Arrayshared_memory
  • 如果共享复杂对象(如字典、列表),建议使用 multiprocessing.Manager,尽管性能稍差但使用方便。
  • 修改字符串:Value('u', 'hello')(Python 3 中不推荐,可用 Array)。
  • 进程退出后,Value 对象依然存活(如果主进程还持有引用),手动删除可调用 del v

总结

Value 是进程间共享单个变量的便捷工具,默认带锁保证线程安全。

对于复杂数据或不需要极致性能的场景,Manager 可能是更简单的选择。

但在高性能计数、标志位等场景下,Value 非常高效。

声明:本文为原创文章,51blog.xyz和作者拥有版权,如需转载,请注明来源于51blog.xyz并保留原文链接:https://www.51blog.xyz/article/134.html

文章归档

推荐文章

buildadmin logo
Thinkphp8 Vue3 Element PLus TypeScript Vite Pinia

🔥BuildAdmin是一个永久免费开源,无需授权即可商业使用,且使用了流行技术栈快速创建商业级后台管理系统。

热门标签

PHP ThinkPHP ThinkPHP5.1 Go Mysql Mysql5.7 Redis Linux CentOS7 Git HTML CSS CSS3 Javascript JQuery Vue LayUI VMware Uniapp 微信小程序 docker wiki Confluence7 学习笔记 uView ES6 Ant Design Pro of Vue React ThinkPHP6.0 chrome 扩展 翻译工具 Nuxt SSR 服务端渲染 scrollreveal.js ThinkPHP8.0 Mac webman 跨域CORS vscode GitHub ECharts Canvas vue3 three.js 微信支付 PHP全栈开发 Python AI 人工智能 AI生成 工作经验 实战笔记