What I would like to do is to share a dictionary between subclasses of Process
and when one process updates the dictionary the other is notified to use it. This is illustrated in the code below where MyProducer
starts filling the dictionary and in every iteration triggers an event to notify MyConsumer
to process the dictionary. Everything works apart from the part where the dictionary in MyConsumer
is empty...
from multiprocessing import Process, Manager, Event
class MyProducer(Process):
increment = 0
def __init__(self, dictionary, event):
Process.__init__(self)
self.dictionary = dictionary
self.event = event
def run(self):
while self.increment < 20:
self.dictionary[self.increment]=self.increment+10
self.increment = self.increment + 1
print("From producer: ", self.dictionary)
self.event.set()
while self.event.is_set() is True:
increment = self.increment
increment = increment + 1
class MyConsumer(Process):
def __init__(self, dictionary, event):
Process.__init__(self)
self.dictionary = dictionary
self.event = event
def run(self):
while True:
self.event.wait()
print("From consumer: ", self.dictionary)
self.event.clear()
if __name__ == "__main__":
with Manager() as manager:
state_dict = manager.dict()
state_ready = Event()
producerprocess = MyProducer(state_dict, state_ready)
consumerprocess = MyConsumer(state_dict, state_ready)
producerprocess.start()
consumerprocess.start()
The output is
Process MyProducer-2:
Traceback (most recent call last):
File "/usr/lib/python3.8/multiprocessing/managers.py", line 827, in _callmethod
conn = self._tls.connection
AttributeError: 'ForkAwareLocal' object has no attribute 'connection'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.8/multiprocessing/process.py", line 315, in _bootstrap
self.run()
File "main.py", line 13, in run
self.dictionary[self.increment]=self.increment+10
File "<string>", line 2, in __setitem__
File "/usr/lib/python3.8/multiprocessing/managers.py", line 831, in _callmethod
self._connect()
File "/usr/lib/python3.8/multiprocessing/managers.py", line 818, in _connect
conn = self._Client(self._token.address, authkey=self._authkey)
File "/usr/lib/python3.8/multiprocessing/connection.py", line 502, in Client
c = SocketClient(address)
File "/usr/lib/python3.8/multiprocessing/connection.py", line 630, in SocketClient
s.connect(address)
FileNotFoundError: [Errno 2] No such file or directory
UPDATE
My intention is to understand why the dictionary does not work with the Process subclasses. I know all the cases that work that you can find on the internet. Actually I have a solution that works fine, just replace dict with queue, I want to understand why dict does not work.
from multiprocessing import Process, Queue, Event
class MyProducer(Process):
increment = 0
def __init__(self, queue, event):
Process.__init__(self)
self.queue = queue
self.event = event
def run(self):
while self.increment < 20:
self.queue.put([self.increment,self.increment+10])
self.increment = self.increment + 1
print("From producer: ", self.queue.qsize())
self.event.set()
while self.event.is_set() is True:
increment = self.increment
increment = increment + 1
class MyConsumer(Process):
def __init__(self, queue, event):
Process.__init__(self)
self.queue = queue
self.event = event
def run(self):
while True:
self.event.wait()
print("From consumer: ", self.queue.qsize())
self.event.clear()
if __name__ == "__main__":
state_queue = Queue()
state_ready = Event()
producerprocess = MyProducer(state_queue, state_ready)
consumerprocess = MyConsumer(state_queue, state_ready)
producerprocess.start()
consumerprocess.start()