2

I am trying to use an object (of class Event) between two processes. The main process creates the object (self.event) and passes it to the new process as args. The new process will call the inject() method of the Event() in foo1() and again the main process will call restore when foo2() is called.

from multiprocessing import Process, Queue
class Event:
    def __init__(self):
        print('init')
        self.i = None
    def inject(self):
        print(self.i)
        self.i = 100
        print(self.i)
    def restore(self):
        print(self.i)


class Test:
    def __init__(self):
        self.event = Event()
    def foo1(self):
        p1 = Process(target=self.foo1_target, args=(self.event,))
        p1.start()
        p1.join()
    def foo1_target(self, event):
        event.inject()
    def foo2(self):
        self.event.restore()


t = Test()
t.foo1()
t.foo2()

When I run t.foo1(), it prints

None

100

When I run t.foo2(), it prints

None

My understanding is that t.foo2() should print 100. I am not able to understand why it prints None. Also, how do I use Event object between main process and new process ?

Akal
  • 21
  • 2
  • 1
    You are creating a new process, which means you are taking the data as it is when you fork. That means you have a copy of the Event object and not a reference to the same object. When foo2 is called, self.event is still the Event() object itself within the original process with NO functions or data modifications as those happened in a different process. If you want to share data via multiple processes you should look into Multiprocessing data structures such as Mutliprocessing.Array. check this answer amigo https://stackoverflow.com/questions/10721915/shared-memory-objects-in-multiprocessing – Theodore Howell Sep 17 '19 at 16:38
  • Or consider using a thread pool instead :) – Theodore Howell Sep 17 '19 at 16:38
  • Also a great article, read the multiprocessing part to understand my comments a little better. If this helps and upvotes are appreciated :) https://timber.io/blog/multiprocessing-vs-multithreading-in-python-what-you-need-to-know/ – Theodore Howell Sep 17 '19 at 16:41

1 Answers1

0

I was able to achieve that using Semaphores and Threads from threading. :

from threading import Semaphore, Thread
class Event:
    def __init__(self):
        print('init')
        self.i = None
        self.sem = Semaphore(0)

    def inject(self):0
        print(self.i)
        self.i = 100
        print(self.i)
        self.sem.release()

    def restore(self):
        self.sem.acquire()
        print(self.i, "finished")



class Test:
    def __init__(self):
        self.event = Event() 
    def foo1(self):
        p1 = Thread(target=self.foo1_target, args=())
        p1.start()
        p1.join()
    def foo1_target(self):
        self.event.inject()

    def foo2(self):
        self.event.restore()



if __name__ == '__main__':
    t = Test()
    t.foo1()
    t.foo2()

output

init
None
100
100 finished
developer_hatch
  • 15,898
  • 3
  • 42
  • 75