讲师中心 微信公众号
AI工具推荐 视频效率加速

并行处理中安全修改共享 NumPy 数组的完整教程

风萱君_5763

风萱君_5763

发布时间:2026-11-07 23:27:10

|

589人浏览过

|

来源于php中文网

原创

并行处理中安全修改共享 NumPy 数组的完整教程

本文详解如何在多进程环境下安全、高效地并行修改同一 NumPy 数组,解决因进程内存隔离导致的参数修改无效问题,核心方案是借助 multiprocessing.Array 构建跨进程共享内存缓冲区,并通过全局变量在子进程中映射为可写 NumPy 视图。

本文详解如何在多进程环境下安全、高效地并行修改同一 numpy 数组,解决因进程内存隔离导致的参数修改无效问题,核心方案是借助 `multiprocessing.array` 构建跨进程共享内存缓冲区,并通过全局变量在子进程中映射为可写 numpy 视图。

在 Python 多进程编程中,子进程默认拥有父进程数据的独立副本(通过 fork 或 spawn 创建),因此直接将 NumPy 数组传入 multiprocessing.Pool 或 joblib.Parallel 时,各进程对数组的修改仅作用于本地副本,无法反映到主进程——这正是原问题中 a 值始终未变的根本原因。

要实现真正的“并行修改同一数组”,必须绕过内存拷贝,使用进程间共享内存(shared memory)。NumPy 本身不直接支持跨进程可写视图,但可通过 multiprocessing.Array 分配底层共享缓冲区,并用 np.ndarray(..., buffer=...) 构造指向该缓冲区的 NumPy 数组视图。关键在于:共享的是内存地址,而非数据对象。

以下为完整、健壮的实现方案,包含三部分核心组件:

✅ 1. 共享内存桥接工具函数

import numpy as np
import multiprocessing

def np_array_to_shared_array(np_array: np.ndarray, lock: bool = False) -> multiprocessing.Array:
    """将 NumPy 数组内容复制到 multiprocessing.Array 共享缓冲区"""
    # 'B' 表示 uint8;根据 dtype 动态选择类型码(简化版以 uint8 为例)
    typecode = np.dtype(np_array.dtype).char
    shared_array = multiprocessing.Array(typecode, np_array.nbytes, lock=lock)

    # 将原始数组数据拷贝进共享缓冲区
    buffer = shared_array.get_obj() if lock else shared_array
    shared_np = np.frombuffer(buffer, dtype=np_array.dtype)
    shared_np[:] = np_array.ravel()  # 注意:flatten() 返回副本,ravel() 更高效
    return shared_array

def shared_array_to_np_array(shared_array: multiprocessing.Array,
                             shape: tuple, dtype: np.dtype) -> np.ndarray:
    """从共享 Array 构造可写 NumPy 数组视图(共享同一内存)"""
    buffer = shared_array.get_obj() if hasattr(shared_array, 'get_obj') else shared_array
    return np.ndarray(shape, dtype=dtype, buffer=buffer)

⚠️ 注意:lock=False 适用于无竞争写入场景(如本例中偶/奇索引严格分离);若存在并发写同一位置风险,需启用 lock=True 并在写操作前后加锁。

✅ 2. 进程初始化与目标函数设计

子进程无法直接访问主进程变量,因此需通过 initializer 将共享数组绑定为模块级全局变量,确保每个工作进程都能访问同一内存:

# 全局变量,供所有子进程访问
a = None

def init_pool(shared_array, shape, dtype):
    global a
    a = shared_array_to_np_array(shared_array, shape, dtype)

def test(i):
    """无需再接收数组参数 —— 直接操作全局共享数组 a"""
    n = a.shape[0]
    if i % 2 == 0:
        a[0:n:2] = 2  # 向量化赋值,比循环更高效
    else:
        a[1:n:2] = 1

✅ 优势:避免参数传递开销;逻辑清晰;天然支持任意数量的并行任务(只需传入 [0,1,2,...])。

✅ 3. 主程序:安全启动与结果验证

def main():
    # 初始化原始数组
    arr = np.zeros(10, dtype=np.uint8)
    shape, dtype = arr.shape, arr.dtype

    # 创建共享内存并映射回 NumPy 视图(主进程也通过此视图操作)
    shared_arr = np_array_to_shared_array(arr, lock=False)
    arr = shared_array_to_np_array(shared_arr, shape, dtype)  # 此 arr 即共享视图

    # 启动进程池,指定初始化器和参数
    with multiprocessing.Pool(
        processes=2,
        initializer=init_pool,
        initargs=(shared_arr, shape, dtype)
    ) as pool:
        pool.map(test, [0, 1])  # 并行执行两个任务

    print(arr)  # 输出: [2 1 2 1 2 1 2 1 2 1]

if __name__ == '__main__':
    main()

? 关键要点总结

  • 绝不传递数组本身:Pool.starmap(Test, [(i, a, ...)]) 中的 a 是副本,无效;
  • 共享内存 ≠ 共享对象:multiprocessing.Array 提供底层字节缓冲区,np.ndarray(buffer=...) 提供语义层视图;
  • 初始化器(initializer)是桥梁:它在每个子进程启动时运行一次,将共享缓冲区绑定为全局变量;
  • 向量化优于显式循环:a[0::2] = 2 比 for x in range(0,n,2): a[x]=2 更简洁、更快、更安全;
  • dtype 对齐至关重要:multiprocessing.Array 的类型码(如 'B')必须与 NumPy dtype 精确匹配,否则内存解释错误;
  • spawn 启动方式兼容性更好:Windows/macOS 默认用 spawn,上述代码在所有平台均适用(无需 if __name__ == '__main__': 保护也可运行,但保留更稳妥)。

该方案平衡了性能、可读性与跨平台鲁棒性,是科学计算中并行更新大型共享数组的标准实践。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

1891

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

5184

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

1829

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

31297

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

3707

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

3727

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

1243

2023.08.11

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

616

2023.08.10

Postman身份认证怎么配置
Postman身份认证怎么配置

本专题从实际API接口调试场景出发,讲解Postman身份认证的完整配置流程,包括常见认证协议介绍、授权参数设置、访问令牌填写、OAuth 2.0授权及认证失败排查,帮助用户正确完成接口授权与访问验证。

0

2026.11.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn