Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python进程之间共享内存中的大型数据结构?_Python_Performance_Numpy_Pandas_Architecture - Fatal编程技术网

在Python进程之间共享内存中的大型数据结构?

在Python进程之间共享内存中的大型数据结构?,python,performance,numpy,pandas,architecture,Python,Performance,Numpy,Pandas,Architecture,我们在Linux机器上运行了大约10个Python进程,所有进程都读取相同的大数据结构(这恰好是一个PandasDataFrame,本质上是一个2D numpy矩阵) 这些过程必须尽快响应查询,而将数据保存在磁盘上已经不能满足我们的需要 我们真正需要的是所有进程对内存中的数据结构进行完全随机访问,以便它们能够检索执行任意计算所需的所有元素 由于数据结构的大小,我们无法在内存中复制10次(甚至两次) 有没有办法让所有10个Python进程共享对内存中数据结构的随机访问?(COW)在fork()上,

我们在Linux机器上运行了大约10个Python进程,所有进程都读取相同的大数据结构(这恰好是一个Pandas
DataFrame
,本质上是一个2D numpy矩阵)

这些过程必须尽快响应查询,而将数据保存在磁盘上已经不能满足我们的需要

我们真正需要的是所有进程对内存中的数据结构进行完全随机访问,以便它们能够检索执行任意计算所需的所有元素

由于数据结构的大小,我们无法在内存中复制10次(甚至两次)

有没有办法让所有10个Python进程共享对内存中数据结构的随机访问?

(COW)在
fork()
上,数据不会被复制 除非是写给我的

因此,如果在全局名称空间中定义数据帧,
df
,则 可以从任意多个后续生成的子流程访问它, 数据帧不需要额外的内存

只有当其中一个子进程修改了
df
(或与
df
在同一内存页上的数据)时,才会复制(在该内存页上的)数据

因此,听起来很奇怪,在Linux上,除了在生成子进程之前在全局名称空间中定义数据外,您不必在子进程之间共享对大型内存中数据结构的访问

演示写时复制行为


当数据被修改时,它所在的内存页将被复制。 如中所述:

每个进程都有一个页表,它将其虚拟地址映射到 实际地址;执行fork()操作时,新的 流程创建了一个新的页面表,其中每个条目都被标记 具有“写入时复制”标志;这也是为调用方的 地址空间。当要更新内存内容时 标志被选中。如果设置了,则会分配一个新页面,其中的数据 复制旧页,在新页上进行更新,然后 已清除新页的“写入时复制”标志

因此,如果对内存页上的某个值进行了更新,则该页将被删除 抄袭的。如果大数据帧的一部分驻留在该内存页上,则只复制该部分,而不复制整个数据帧。 但根据具体情况,可能会更大

类型


查找系统上的页面大小(以字节为单位)。

另一种解决方案存在一个相当大的问题,即要求数据帧始终是静态的,并且需要Linux

您应该看看Redis,它虽然没有本地python内存结构那么快,但在同一台机器上查询类似表的对象仍然非常快。如果您希望通过共享内存结构实现最高速度,请查看这个刚刚起步的项目


两者都提供了动态数据功能和跨语言支持的巨大优势,而Redis还允许您使用多节点

这些进程是仅从数据帧读取,还是同时读取和写入(修改数据帧)?您使用的是什么操作系统?@unutbu:它们只是在读取数据——数据是由不同的进程写入的,基本上是静态的,并且一经写入就只读。另外,这是Linux(Ubuntu服务器14.04)。谢谢!关于奶牛什么时候出生有什么特别规定吗?例如,如果顶级
\uuuuuu主\uuuuu
进程包含一大堆全局数据,该怎么办。您链接的COW解释是指“内存页”。其中一个分叉进程可能会触发
df
的完整副本,仅仅因为它试图(过度)写入从
\uuuuuu main\uuuuuuuu
继承的任何更小的数据结构?@DunPeal:只复制受影响的内存页。我在上面添加了更多的细节。太好了!最后一个问题是:我是否必须像您的示例中那样使用
多处理.Process
生成这些工作人员,以便他们能够访问
\uuuuuuu main\uuuuuu
的全局范围,或者是否有其他方法可以为他们提供此类访问?例如,是否有任何方法可以使它在不太花哨的
子进程.Popen
中工作?您需要使用
多处理
或(在Python3中)
并发.futures
。让你开始。
% getconf PAGE_SIZE
4096