python 共享内存容量_Python多进程共享内存与使用参数

本文探讨了在Python多进程中如何有效地共享内存,包括通过pickle传递数据的潜在性能问题,以及使用`multiprocessing.Pool`的初始化方法来减少复制和提高效率。通过避免多次pickle/unpickle操作和利用fork的写时复制特性,可以优化大型数据结构的处理。文中提供了使用`initializer`参数的示例代码,以实现更高效的内存共享。
摘要由CSDN通过智能技术生成

我将从第二和第三种方法开始,因为它们更容易解释。在

将参数传递给pool.map或pool.apply时,参数将被pickle,使用管道发送到子进程,然后在子进程中取消拾取。当然,这需要传递的数据结构的两个完全不同的副本。它还可能导致大数据结构的性能降低,因为pickle/unpickle大型对象需要相当长的时间。在

使用第三种方法,只需传递比方法2更小的数据结构。这应该会表现得更好,因为您不需要对太多的数据进行pickle/unpickle。在

另外一个注释-多次传递data绝对是个坏主意,因为每个副本都会反复地被pickle/unpickle。你想把它传给每个孩子一次。方法1是一种很好的方法,或者可以使用initializer关键字参数显式地将data传递给子对象。这将在Linux上使用fork,在Windows上使用pickle将数据传递给子进程:import pandas as pd

import numpy as np

from multiprocessing import Pool

data = None

def init(_data):

global data

data = _data # data is now accessible in all children, even on Windows

# method #1

def foo(i): return data[i]

if __name__ == '__main__':

data = pd.Series(np.array(range(100000)))

pool = Pool(2, initializer=init, initargs=(data,))

print pool.map(foo,[10,134,8,1])

使用第一种方法,您将利用fork的行为来允许子进程继承data对象。fork具有写时复制语义,这意味着内存实际上是在父级和子级之间共享的,直到您尝试在子级中写入内存。当您尝试写入时,必须复制您要写入的数据所在的内存页,以使其与父版本分开。在

现在,这听起来像一个灌篮-不需要复制任何东西,只要我们不写它,这肯定比pickle/unpickle方法快。通常都是这样。然而,在实践中,Python是在内部写入其对象,即使您并不期望它这样做。因为Python使用引用计数来管理内存,所以每次传递给方法或分配给变量等时,它都需要增加每个对象的内部引用计数器。因此,包含传递给子进程的每个对象的引用计数的内存页最终将被复制。与多次pickling data相比,这肯定更快,占用的内存更少,但也不是完全共享的。在

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值