我正在处理大量数据,存储在字典中,使用多重处理。基本上,我所做的就是加载一些签名,存储在字典中,从其中构建一个共享的dict对象(获取Manager.dict()返回的' proxy‘对象),并将这个代理作为参数传递给在多进程中必须执行的函数。
我只想澄清:
signatures = dict()
load_signatures(signatures)
[...]
manager = Manager()
signaturesProxy = manager.dict(signatures)
[...]
result = pool.map ( myfunction , [ signaturesProxy ]*NUM_CORES )现在,如果签名小于200万个条目,那么一切都是完美的。无论如何,我必须处理一个包含5.8M键的字典(二进制格式的酸洗签名会生成一个4.8GB的文件)。在这种情况下,进程在创建代理对象时死亡:
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的使用开始迅速减少,进程以上述错误结束。所以我想这不是因为内存不足.
有什么想法或建议吗?
谢谢,
戴维德
发布于 2010-12-26 18:31:19
如果字典是只读的,则在大多数操作系统中不需要代理对象。
只需在开始工作之前加载字典,并将它们放在可以到达的位置;最简单的位置是全局到模块。工人们都能读懂它们。
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上工作;它的(残废的)进程模型需要为每个工作人员重新启动整个进程,因此它不太擅长共享数据。
发布于 2010-12-26 17:27:01
你为什么不用数据库试试呢?数据库不仅限于可嵌入/物理内存,而且对多线程/进程使用是安全的。
发布于 2010-12-26 17:24:26
为了节省时间和不需要调试系统级的问题,也许您可以将580万本记录字典分成三组,每组2百万,并运行3次。
https://stackoverflow.com/questions/4534687
复制相似问题