首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >python:使用多处理共享大型字典

python:使用多处理共享大型字典
EN

Stack Overflow用户
提问于 2010-12-26 17:15:32
回答 4查看 5.3K关注 0票数 8

我正在处理大量数据,存储在字典中,使用多重处理。基本上,我所做的就是加载一些签名,存储在字典中,从其中构建一个共享的dict对象(获取Manager.dict()返回的' proxy‘对象),并将这个代理作为参数传递给在多进程中必须执行的函数。

我只想澄清:

代码语言:javascript
运行
复制
signatures = dict()
load_signatures(signatures)
[...]
manager = Manager()
signaturesProxy = manager.dict(signatures)
[...]
result = pool.map ( myfunction , [ signaturesProxy ]*NUM_CORES )

现在,如果签名小于200万个条目,那么一切都是完美的。无论如何,我必须处理一个包含5.8M键的字典(二进制格式的酸洗签名会生成一个4.8GB的文件)。在这种情况下,进程在创建代理对象时死亡:

代码语言:javascript
运行
复制
Traceback (most recent call last):
  File "matrix.py", line 617, in <module>
signaturesProxy = manager.dict(signatures)
  File "/usr/lib/python2.6/multiprocessing/managers.py", line 634, in temp
token, exp = self._create(typeid, *args, **kwds)
  File "/usr/lib/python2.6/multiprocessing/managers.py", line 534, in _create
id, exposed = dispatch(conn, None, 'create', (typeid,)+args, kwds)
  File "/usr/lib/python2.6/multiprocessing/managers.py", line 79, in dispatch
raise convert_to_error(kind, result)
multiprocessing.managers.RemoteError: 
---------------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.6/multiprocessing/managers.py", line 173, in handle_request
    request = c.recv()
EOFError
---------------------------------------------------------------------------

我知道数据结构是巨大的,但我在一台配备了w/ 32 7GB的机器上工作,运行在上面我看到,在加载签名之后,进程占用了7GB的RAM。然后,它开始构建代理对象,RAM的使用量达到~17 32的RAM,但从未接近32。此时,RAM的使用开始迅速减少,进程以上述错误结束。所以我想这不是因为内存不足.

有什么想法或建议吗?

谢谢,

戴维德

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-12-26 18:31:19

如果字典是只读的,则在大多数操作系统中不需要代理对象。

只需在开始工作之前加载字典,并将它们放在可以到达的位置;最简单的位置是全局到模块。工人们都能读懂它们。

代码语言:javascript
运行
复制
from multiprocessing import Pool

buf = ""

def f(x):
    buf.find("x")
    return 0

if __name__ == '__main__':
    buf = "a" * 1024 * 1024 * 1024
    pool = Pool(processes=1)
    result = pool.apply_async(f, [10])
    print result.get(timeout=5)

这只会使用1GB的内存,而不是每个进程的1GB,因为任何现代操作系统都会对在分叉之前创建的数据进行复制。请记住,其他工作人员不会看到对数据的更改,当然,内存将分配给您更改的任何数据。

它将使用一些内存:包含引用计数的每个对象的页面将被修改,因此将被分配。这是否重要取决于数据。

这将在任何实现普通分叉的操作系统上工作。它不能在Windows上工作;它的(残废的)进程模型需要为每个工作人员重新启动整个进程,因此它不太擅长共享数据。

票数 -3
EN

Stack Overflow用户

发布于 2010-12-26 17:27:01

你为什么不用数据库试试呢?数据库不仅限于可嵌入/物理内存,而且对多线程/进程使用是安全的。

票数 6
EN

Stack Overflow用户

发布于 2010-12-26 17:24:26

为了节省时间和不需要调试系统级的问题,也许您可以将580万本记录字典分成三组,每组2百万,并运行3次。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4534687

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档