use*_*645 5 python singleton multithreading multiprocessing parallel-python
我有一个类,该类将应用程序所需的所有资源(主要是图像)加载到内存中。
然后,几个线程需要通过此类访问这些资源。我不希望每个实例都重新加载所有资源,所以我以为我使用了Singleton模式。我这样做是这样的:
class DataContainer(object):
_instance = None
_lock = threading.Lock()
_initialised = True
def __new__(cls, *args, **kwargs):
with cls._lock:
if not cls._instance:
cls._initialised = False
cls._instance = object.__new__(cls, *args, **kwargs)
return cls._instance
def __init__(self, map_name = None):
# instance has already been created
if self._initialised:
return
self._initialised = True
# load images
Run Code Online (Sandbox Code Playgroud)
只要我不使用多个线程,它就可以正常工作。但是对于多个线程,每个线程都有一个不同的实例。因此,使用4个线程,它们每个都创建一个新实例。我希望所有线程都使用此类的相同实例,因此资源仅一次加载到内存中。
我也尝试在定义类的同一模块中执行此操作,但在类定义之外:
def getDataContainer():
global dataContainer
return dataContainer
dataContainer = DataContainer()
Run Code Online (Sandbox Code Playgroud)
但是每个线程仍然有自己的实例。
我是python的新手,如果这是错误的方法,请让我知道,谢谢您的帮助
为了扩展@Will的注释,如果父级创建了一个“共享对象”,然后传递给每个线程,则所有线程将共享同一对象。
(有关进程,请参阅multiprocessing.Manager类,该类直接支持共享状态,包括修改的状态。)
import threading, time
class SharedObj(object):
image = 'beer.jpg'
class DoWork(threading.Thread):
def __init__(self, shared, *args, **kwargs):
super(DoWork,self).__init__(*args, **kwargs)
self.shared = shared
def run(self):
print threading.current_thread(), 'start'
time.sleep(1)
print 'shared', self.shared.image, id(self.shared)
print threading.current_thread(), 'done'
myshared = SharedObj()
threads = [ DoWork(shared=myshared, name='a'),
DoWork(shared=myshared, name='b')
]
for t in threads:
t.start()
for t in threads:
t.join()
print 'DONE'
Run Code Online (Sandbox Code Playgroud)
输出:
<DoWork(a, started 140381090318080)> start
<DoWork(b, started 140381006067456)> start
shared beer.jpg shared140381110335440
<DoWork(b, started 140381006067456)> done
beer.jpg 140381110335440
<DoWork(a, started 140381090318080)> done
DONE
Run Code Online (Sandbox Code Playgroud)
请注意,线程ID不同,但是它们都使用相同的SharedObj实例,在以440结尾的内存地址处。