首页 > 系统相关 >Python基础_多进程数据共享

Python基础_多进程数据共享

时间:2024-03-12 18:26:05浏览次数:29  
标签:__ RawValue Python value RawArray Process 数据共享 进程 multiprocessing

Python基础_多进程数据共享

一、多进程数据共享

Python中,多进程之间的数据共享是一个复杂的主题,因为每个进程都有自己的内存空间和独立的Python解释器实例。这意味着它们不能直接共享数据,就像线程那样。但是,Python提供了几种方法来间接地实现多进程之间的数据共享。

二、使用multiprocessing.Manager对象

multiprocessing模块提供了一个Manager对象,它可以让创建可以在多个进程之间共享的数据结构,如列表和字典。Manager对象背后实际上是通过进程间通信(IPC)实现的。

**使用示例:**创建可以在多个进程之间共享的字典

from multiprocessing import Process, Manager

def func(d, i):
    d[i] = i * i

if __name__ == '__main__':
    with Manager() as manager:
        d = manager.dict()
        processes = [Process(target=func, args=(d, i)) for i in range(10)]
        for p in processes:
            p.start()
        for p in processes:
            p.join()
        print(d)
# 执行结果
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

三、使用multiprocessing.Value和multiprocessing.Array

这两个类允许创建可以在多个进程之间共享的值和数组。

它们是基于ctypes模块的,这意味着可以创建不同类型的数据结构(如整数、浮点数数组等)。

**使用示例:**使用共享类ValueArray

from multiprocessing import Process, Value, Array

def func(n, a):
    n.value = 3.1415927
    for i in range(len(a)):
        a[i] **= 2

if __name__ == '__main__':
    num = Value('d', 0.0)
    arr = Array('i', range(10))

    p = Process(target=func, args=(num, arr))
    p.start()
    p.join()

    print(num.value)
    print(arr[:])
# 执行结果
3.1415927
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

四、使用管道和队列

尽管不是真正的“共享”数据,但multiprocessing.Pipemultiprocessing.Queue提供了进程间通信的机制。

这些对象可以在进程之间传递数据,从而实现某种形式的数据“共享”。

使用示例:Queue数据共享

from multiprocessing import Process, Queue

def func(q, i):
    q.put('hello {} times'.format(i))

if __name__ == '__main__':
    q = Queue()
    plist= [Process(target=func, args=(q, i)) for i in range(3)]
    for p in plist:
        p.start()
        p.join()
    while not q.empty():
        tmpVal = q.get()
        print(tmpVal)
# 执行结果
hello 0 times
hello 1 times
hello 2 times

五、使用共享内存

在某些情况下,可能需要直接使用操作系统的共享内存机制。可以通过multiprocessing.RawValuemultiprocessing.RawArray类来实现,但它们提供了更低的抽象级别,需要谨慎使用。

multiprocessing.RawValuemultiprocessing.RawArray 用于创建可以直接在多个进程之间共享的内存区域。

ManagerValueArray 不同,RawValueRawArray 不提供任何锁机制,因此它们更快,但同时也需要程序员负责同步以避免数据竞争。

使用 RawValueRawArray 示例:

from multiprocessing import Process, RawValue, RawArray, Lock

# 使用RawValue
def process_with_raw_value(value, lock):
    with lock:
        for _ in range(10000):  # 假设有很多次写操作
            value.value += 1

# 使用RawArray
def process_with_raw_array(arr, lock):
    with lock:
        for i in range(len(arr)):
            arr[i] **= 2  # 对数组中的每个元素进行平方操作

if __name__ == '__main__':
    # 创建一个RawValue对象,初始值为0,类型为'i'(整数)
    lock = Lock()  # 创建一个锁对象用于同步
    shared_value = RawValue('i', 0)

    # 创建一个RawArray对象,包含5个整数元素
    shared_array = RawArray('i', [1, 2, 3, 4, 5])

    # 创建并启动两个进程,分别处理RawValue和RawArray
    p1 = Process(target=process_with_raw_value, args=(shared_value, lock))
    p2 = Process(target=process_with_raw_array, args=(shared_array, lock))

    p1.start()
    p2.start()

    p1.join()
    p2.join()

    # 由于RawValue和RawArray不提供同步机制,们需要使用锁来确保数据一致性
    with lock:
        print("Shared value:", shared_value.value)  # 输出共享值的最终结果
        print("Shared array:", shared_array[:])     # 输出共享数组的最终结果
# 执行结果
Shared value: 10000
Shared array: [1, 4, 9, 16, 25]

注意:尽管 RawValueRawArray 提供了更高的性能和更灵活的数据共享方式,但它们也更难正确使用,因为需要程序员自己处理所有的同步问题。在大多数情况下,如果不需要这么底层的控制,使用 ManagerValueArray 会更简单和安全。

六、注意事项

由于GIL(全局解释器锁)的存在,共享数据在并发修改时可能会导致不可预知的行为。

因此,在共享数据时,请务必确保正确地同步进程,以避免数据竞争和不一致。


may the odds be ever in your favor ~

标签:__,RawValue,Python,value,RawArray,Process,数据共享,进程,multiprocessing
From: https://blog.csdn.net/weixin_36928396/article/details/136632023

相关文章

  • 3/12学习进程
    大二学期第三周日报 第一天第二天第三天第四天第五天所花时间(包括上课) 210min90min   代码量(行) 350 200   博客量(篇) 1 1   了解到的知识点编写安卓增删改查,使用sqlite存储数据 验收增删改查,做个人......
  • python 递归比较两个文件夹
    以下importfilecmp,osdefcompare_folders(folder1,folder2):dcmp=filecmp.dircmp(folder1,folder2)fornameindcmp.left_only:print(f"{folder1}单独存在的文件:{name}")fornameindcmp.right_only:print(f"{folder......
  • Python函数每日一讲 - id()
    引言几天不见,今天我们来看看一个比较特别的函数id(),这个函数就是用来获取对象在内存中的唯一标识符的函数。语句概览id()函数是Python内置函数之一,用于获取对象在内存中的唯一标识符。其语法格式如下:id(object)其中,object参数是要获取标识符的对象。函数实例例1:获取整数......
  • macOS 下使用 pyenv 安装 python 2.n.p 报错,ERROR: The Python zlib extension was no
    TL;DR执行brewinstallzlib安装zlib之后,根据安装信息提示将一下三行变量exportLDFLAGS="-L/opt/homebrew/opt/zlib/lib"exportCPPFLAGS="-I/opt/homebrew/opt/zlib/include"exportPKG_CONFIG_PATH="/opt/homebrew/opt/zlib/lib/pkgconfig"加入到~/.zsh......
  • python得scrapy提取数据 xpath注意事项
    在提取器过滤数据这个地方被坑了很久,确实有点坑,有点难以理解,多注意下就可以了。frommultiprocessingimportallow_connection_picklingfromscrapy.spidersimportSpiderfrom..itemsimportCnblogshaha01ItemclasscnblogSpider(Spider):name="cnblogsHAHA01"#定......
  • Python 列表中任意字符串是否存在的判断
    `importsysjudge_string=[]target_string=sys.argvjudge_string=['-?','/?','--?','-help','--help','help']target_string=sys.argvjudge_result=any(wordifwordintarget_stringelseFals......
  • Python - whl文件是什么?怎么安装?
    whl文件是什么?.whl文件是Python分发的一种标准内置包格式,通常称为“轮子(wheel)”。123这种格式允许Python用户安装和分发第三方库,.whl文件包含了Python模块的压缩形式(.py文件和经过编译的.pyd文件)以及这些模块的元数据。它们通常通过Zip压缩算法进行压缩,可以......
  • 基于WiFi的防盗报警Python脚本
    学校图书馆有一本电子书,可以供学生阅读,但是怎么防止学生将其带出图书馆呢?我把它连上馆内的一台电脑的WiFi热点,间隔一段时间就从电脑ping这台电子书,如果ping不通,说明电子书脱离了WiFi信号范围,电脑就会响起报警声。代码思路如下,先通过Windows上的arp命令,用设备的MAC地址获取其IP,再......
  • Linux之ps -ef进程命令及netstat网络状态命令简记
    ps-ef释义:ps-ef表示查看全格式的全部进程。ps是linux下最常用的也是非常强大的进程查看命令,常配合管道命令|和查找命令grep同时执行来查看特定进程。参数含义:-e显示所有进程。-f全格式。-h不显示标题。-l长格式。-w宽输出。a显示终端上的所有进程,包括其他用户的......
  • 用Python编写自己的微型Redis
    building-a-simple-redis-server-with-python前几天我想到,写一个简单的东西会很整洁 雷迪斯-像数据库服务器。虽然我有很多WSGI应用程序的经验,数据库服务器展示了一种新颖挑战,并被证明是学习如何工作的不错的实际方法Python中的套接字。在这篇文章中,我将分享我在此过程中......