gpt4 book ai didi

python 多处理挂起,潜在的队列内存错误?

转载 作者:行者123 更新时间:2023-11-28 17:48:39 25 4
gpt4 key购买 nike

我最近发布了一个问题 Using multiprocessing for finding network paths很高兴@unutbu 提供了一个简洁的解决方案

但是,我在执行 test_workers()(利用多处理)函数时遇到了困难。代码运行,但在我的网络 G

中有大量节点 N 时挂起

使用 Mac OS X Lion 10.7.5 -- python 2.7 运行,当 N>500 时挂起。日志记录带来以下消息,之后它挂起

[DEBUG/MainProcess] doing self._thread.start()
[DEBUG/MainProcess] starting thread to feed data to pipe
[DEBUG/MainProcess] ... done self._thread.start()

通过 VMware Fusion 在 Windows 7 上运行有助于更大的网络,但最终会在 N> 20,000 个节点附近挂起图形(理想情况下,我希望在 N = 500,000 个网络上使用它)。挂起时来自 window 一侧的消息:

[DEBUG/MainProcess] starting thread to feed data to pipe
[DEBUG/MainProcess] ... done self._thread.start()[DEBUG/MainProcess] telling queue thread to quit
Traceback (most recent call last):
File "C:\Users\Scott\Desktop\fp_test.py", line 75, in <module>
Traceback (most recent call last):
File "C:\Python27\lib\multiprocessing\queues.py", line 264, in _feed
test_workers()
MemoryError

我想知道是否有人知道为什么会发生这种情况?以及是否有关于如何让它适用于更大的网络的任何建议?

非常感谢您提出的任何建议。

@unutbu 的代码:

import networkx as nx
import multiprocessing as mp
import random
import sys
import itertools as IT
import logging
logger = mp.log_to_stderr(logging.DEBUG)


def worker(inqueue, output):
result = []
count = 0
for pair in iter(inqueue.get, sentinel):
source, target = pair
for path in nx.all_simple_paths(G, source = source, target = target,
cutoff = None):
result.append(path)
count += 1
if count % 10 == 0:
logger.info('{c}'.format(c = count))
output.put(result)

def test_workers():
result = []
inqueue = mp.Queue()
for source, target in IT.product(sources, targets):
inqueue.put((source, target))
procs = [mp.Process(target = worker, args = (inqueue, output))
for i in range(mp.cpu_count())]
for proc in procs:
proc.daemon = True
proc.start()
for proc in procs:
inqueue.put(sentinel)
for proc in procs:
result.extend(output.get())
for proc in procs:
proc.join()
return result

def test_single_worker():
result = []
count = 0
for source, target in IT.product(sources, targets):
for path in nx.all_simple_paths(G, source = source, target = target,
cutoff = None):
result.append(path)
count += 1
if count % 10 == 0:
logger.info('{c}'.format(c = count))

return result

sentinel = None

seed = 1
m = 1
N = 1340//m
G = nx.gnm_random_graph(N, int(1.7*N), seed)
random.seed(seed)
sources = [random.randrange(N) for i in range(340//m)]
targets = [random.randrange(N) for i in range(1000//m)]
output = mp.Queue()

if __name__ == '__main__':
test_workers()
# test_single_worker()
# assert set(map(tuple, test_workers())) == set(map(tuple, test_single_worker()))

最佳答案

您遇到了 logging 模块的死锁。

该模块保留了一些线程锁以允许跨线程进行安全日志记录,但是当当前进程被 fork 时它不能很好地发挥作用。参见示例 here了解正在发生的事情。

解决方案是删除 logging 调用或改用普通 print

无论如何,作为一般规则,避免使用线程+ fork 。并始终检查哪些模块在后台使用线程。

请注意,在 Windows 上它可以正常工作,因为 Windows 没有 fork,因此不存在锁克隆和随后的死锁问题。在这种情况下,MemoryError 表示进程消耗了过多的 RAM。您可能需要重新考虑使用更少 RAM 的算法,但这与您在 OSX 上遇到的问题完全不同

关于python 多处理挂起,潜在的队列内存错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14087527/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com