使用多处理在类内共享属性
问题描述
我有一个以字典为属性的类。在这个类中,我运行multiprocessing
来填写Queue
,然后使用其他过程对Queue
中的项执行一些计算。当满足条件时,我将结果存储在此词典中,但我发现当进程希望在词典中存储值时,词典键不在词典中。
class RNG():
def __init__(self):
self.mydict = {}
self.done = False
self.q = Queue(maxsize = 100)
self.lock = Lock()
def _fill_queue(self):
while not self.done:
rng = randint(1,9e6)
if rng % 2 ==0:
_type = 'even'
if 'even' not in self.mydict.keys():
self.mydict['even'] = []
else:
_type = 'odd'
if 'odd' not in self.mydict.keys():
self.mydict['odd'] = []
while self.q.full():
sleep(10)
self.lock.acquire()
self.q.put((_type,rng))
self.lock.release()
def _process_queue(self):
while not self.done:
self.lock.acquire()
if self.q.empty():
self.lock.release()
continue
_type,num = self.q.get()
self.lock.release()
print(f'Appending {_type} number!')
self.mydict[_type].append(num)
self._check_for_exit()
def _check_for_exit(self):
if len(self.mydict['odd']) >= 1e6 and len(self.mydict['even'])>=1e6:
self.done = True
def run(self):
jobs = []
p = Process(target = self._fill_queue)
jobs.append(p)
p.start()
for _ in range(5):
p = Process(target = self._process_queue)
jobs.append(p)
p.start()
for job in jobs:
job.join()
if __name__ == '__main__':
rng = RNG()
rng.run()
当我运行此命令时,尝试在词典中追加数字时出现以下错误:
KeyError: 'even'
KeyError: 'odd'
为什么没有将密钥添加到词典中?另外,如果每个进程都设法写入一个文件,并且该文件具有相同的名称,这是否意味着我需要实现某种信号量或Pipe
?
解决方案
请记住,它们作为两个单独的进程运行。它们并不共享内存。每一个都有自己的RNG实例副本,不会看到对方所做的更改。如果您需要在它们之间进行通信,则需要使用队列或管道。
通常,多处理应用程序要做的是建立一个在它们之间传递的命令和对象。该命令有某种动词,外加要操作的数据。所以,当你想要添加一个密钥时,你可以发送(‘Add’,‘Even’)或类似的东西。然后,您的队列处理程序可以执行几种不同的操作。相关文章