在我的python应用程序中,我需要启动多个multiprocessing.Manager。我似乎在第二个管理器启动时,第一个管理器中引用的所有对象都获得INCREF。 在第三次启动时,第一个和第二个管理器创建的所有对象都获得另一个INCREF。等等。 我无法理解为什么一个全新的经理的开始,在一个新的过程中,会导致所有这些INCREF关于托管在其他经理上的对象 - 这导致程序永远开始/停止。
这个小脚本完全重现了在python 2.7和3.2中测试的行为:
from __future__ import print_function
import multiprocessing, logging
# # Activate multiprocessing logging
mplog = multiprocessing.get_logger()
mplog.setLevel(multiprocessing.util.DEBUG)
mplog.addHandler(logging.StreamHandler())
objs=[]
def newman(n=50):
global objs
m=multiprocessing.Manager()
print('created')
for i in range(n):
objs.append(m.Value('i',i))
return m
print('#### first man')
m1=newman()
print ('#### second man')
m2=newman()
print ('#### third man')
m3=newman(0)
在第一个管理器启动后,记录器打印出与前50个对象的创建相关的消息。
但是当第二个管理器启动时 - 在它创建任何对象之前 - 记录器会打印出恰好50个INCREF消息。然后跟随有关在管理器2上创建50个新对象的消息。
当第三个管理器启动时 - 在它创建任何对象之前 - 再打印100个INCREF消息。
创建m3后没有看到对象创建消息,因为我将0传递给newman()函数。
当程序结束时,会打印相似数量的DECREF消息。
看来,当我启动一个新的管理器时,它会创建对前一个管理器引用的所有对象的引用。在一个大型应用程序中,这转换为极慢启动/关闭。
任何解决方法?或者至少,有关为什么会发生这种情况的任何解释?
答案 0 :(得分:0)
我想我明白了。
class BaseProxy(object):
# ...
def _incref(self):
# ...
util.debug('INCREF %r', self._token.id)
# ...
def _after_fork(self):
# ...
self._incref()
# ...
您正在使用使用fork创建新进程的Linux计算机。 想法:每次启动管理器时,currrent进程都会分叉并调用_incref。